Acabat de renamar, encara que he descobert cosetes i tindré que fer altra pasaeta
Actualitzat stb_image.h a la última versió
This commit is contained in:
@@ -35,6 +35,10 @@ AnimatedFile loadAnimationFromFile(std::shared_ptr<Texture> texture, std::string
|
|||||||
buffer.counter = 0;
|
buffer.counter = 0;
|
||||||
buffer.current_frame = 0;
|
buffer.current_frame = 0;
|
||||||
buffer.completed = false;
|
buffer.completed = false;
|
||||||
|
buffer.name = "";
|
||||||
|
buffer.speed = 5;
|
||||||
|
buffer.loop = 0;
|
||||||
|
buffer.frames.clear();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -44,7 +48,7 @@ AnimatedFile loadAnimationFromFile(std::shared_ptr<Texture> texture, std::string
|
|||||||
int pos = line.find("=");
|
int pos = line.find("=");
|
||||||
|
|
||||||
// Procesa las dos subcadenas
|
// Procesa las dos subcadenas
|
||||||
if (pos != (int)line.npos)
|
if (pos != static_cast<int>(line.npos))
|
||||||
{
|
{
|
||||||
if (line.substr(0, pos) == "name")
|
if (line.substr(0, pos) == "name")
|
||||||
{
|
{
|
||||||
@@ -366,6 +370,10 @@ bool AnimatedSprite::loadFromVector(std::vector<std::string> *source)
|
|||||||
buffer.counter = 0;
|
buffer.counter = 0;
|
||||||
buffer.current_frame = 0;
|
buffer.current_frame = 0;
|
||||||
buffer.completed = false;
|
buffer.completed = false;
|
||||||
|
buffer.name = "";
|
||||||
|
buffer.speed = 5;
|
||||||
|
buffer.loop = 0;
|
||||||
|
buffer.frames.clear();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -377,7 +385,7 @@ bool AnimatedSprite::loadFromVector(std::vector<std::string> *source)
|
|||||||
int pos = line.find("=");
|
int pos = line.find("=");
|
||||||
|
|
||||||
// Procesa las dos subcadenas
|
// Procesa las dos subcadenas
|
||||||
if (pos != (int)line.npos)
|
if (pos != static_cast<int>(line.npos))
|
||||||
{
|
{
|
||||||
if (line.substr(0, pos) == "name")
|
if (line.substr(0, pos) == "name")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ Director::Director(int argc, char *argv[])
|
|||||||
dbg_init(renderer_);
|
dbg_init(renderer_);
|
||||||
|
|
||||||
// Crea los objetos
|
// Crea los objetos
|
||||||
lang::loadFromFile(getLangFile((lang::lang_e)options.game.language));
|
lang::loadFromFile(getLangFile((lang::Code)options.game.language));
|
||||||
|
|
||||||
Input::init(Asset::get()->get("gamecontrollerdb.txt"));
|
Input::init(Asset::get()->get("gamecontrollerdb.txt"));
|
||||||
initInput();
|
initInput();
|
||||||
@@ -706,20 +706,20 @@ int Director::run()
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene una fichero a partir de un lang_e
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
std::string Director::getLangFile(lang::lang_e lang)
|
std::string Director::getLangFile(lang::Code code)
|
||||||
{
|
{
|
||||||
switch (lang)
|
switch (code)
|
||||||
{
|
{
|
||||||
case lang::ba_BA:
|
case lang::Code::ba_BA:
|
||||||
return Asset::get()->get("ba_BA.txt");
|
return Asset::get()->get("ba_BA.txt");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lang::es_ES:
|
case lang::Code::es_ES:
|
||||||
return Asset::get()->get("es_ES.txt");
|
return Asset::get()->get("es_ES.txt");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lang::en_UK:
|
case lang::Code::en_UK:
|
||||||
return Asset::get()->get("en_UK.txt");
|
return Asset::get()->get("en_UK.txt");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ private:
|
|||||||
// Ejecuta el juego en modo demo
|
// Ejecuta el juego en modo demo
|
||||||
void runDemoGame();
|
void runDemoGame();
|
||||||
|
|
||||||
// Obtiene una fichero a partir de un lang_e
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
std::string getLangFile(lang::lang_e lang);
|
std::string getLangFile(lang::Code code);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|||||||
@@ -2418,9 +2418,9 @@ void Game::initPaths()
|
|||||||
get_ready_bitmap_path_[i] = (int)finish1;
|
get_ready_bitmap_path_[i] = (int)finish1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if (i< STAGE_COUNTER)
|
||||||
{
|
{
|
||||||
get_ready_bitmap_path_[i] = sin[(int)((i - 150) * 1.8f)];
|
get_ready_bitmap_path_[i] = sin[(int)((i - second_part) * 1.8f)];
|
||||||
get_ready_bitmap_path_[i] *= distance2;
|
get_ready_bitmap_path_[i] *= distance2;
|
||||||
get_ready_bitmap_path_[i] += finish1;
|
get_ready_bitmap_path_[i] += finish1;
|
||||||
}
|
}
|
||||||
|
|||||||
146
source/item.cpp
146
source/item.cpp
@@ -5,61 +5,61 @@
|
|||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Item::Item(int kind, float x, float y, SDL_Rect *playArea, std::shared_ptr<Texture> texture, std::vector<std::string> *animation)
|
Item::Item(int kind, float x, float y, SDL_Rect *play_area, std::shared_ptr<Texture> texture, std::vector<std::string> *animation)
|
||||||
: kind(kind), playArea(playArea)
|
: kind_(kind), play_area_(play_area)
|
||||||
{
|
{
|
||||||
sprite = std::make_unique<AnimatedSprite>(texture, "", animation);
|
sprite_ = std::make_unique<AnimatedSprite>(texture, "", animation);
|
||||||
|
|
||||||
enabled = true;
|
enabled_ = true;
|
||||||
timeToLive = 600;
|
time_to_live_ = 600;
|
||||||
accelX = 0.0f;
|
accel_x_ = 0.0f;
|
||||||
floorCollision = false;
|
floor_collision_ = false;
|
||||||
|
|
||||||
if (kind == ITEM_COFFEE_MACHINE)
|
if (kind == ITEM_COFFEE_MACHINE)
|
||||||
{
|
{
|
||||||
width = 28;
|
width_ = 28;
|
||||||
height = 37;
|
height_ = 37;
|
||||||
posX = (((int)x + (playArea->w / 2)) % (playArea->w - width - 5)) + 2;
|
pos_x_ = (((int)x + (play_area->w / 2)) % (play_area->w - width_ - 5)) + 2;
|
||||||
posY = -height;
|
pos_y_ = -height_;
|
||||||
velX = 0.0f;
|
vel_x_ = 0.0f;
|
||||||
velY = -0.1f;
|
vel_y_ = -0.1f;
|
||||||
accelY = 0.1f;
|
accel_y_ = 0.1f;
|
||||||
collider.r = 10;
|
collider_.r = 10;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = 20;
|
width_ = 20;
|
||||||
height = 20;
|
height_ = 20;
|
||||||
posX = x;
|
pos_x_ = x;
|
||||||
posY = y;
|
pos_y_ = y;
|
||||||
velX = -1.0f + ((rand() % 5) * 0.5f);
|
vel_x_ = -1.0f + ((rand() % 5) * 0.5f);
|
||||||
velY = -4.0f;
|
vel_y_ = -4.0f;
|
||||||
accelY = 0.2f;
|
accel_y_ = 0.2f;
|
||||||
collider.r = width / 2;
|
collider_.r = width_ / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite->setPosX(posX);
|
sprite_->setPosX(pos_x_);
|
||||||
sprite->setPosY(posY);
|
sprite_->setPosY(pos_y_);
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centra el objeto en la posición X
|
// Centra el objeto en la posición X
|
||||||
void Item::allignTo(int x)
|
void Item::allignTo(int x)
|
||||||
{
|
{
|
||||||
posX = float(x - (width / 2));
|
pos_x_ = float(x - (width_ / 2));
|
||||||
|
|
||||||
if (posX < param.game.play_area.rect.x)
|
if (pos_x_ < param.game.play_area.rect.x)
|
||||||
{
|
{
|
||||||
posX = param.game.play_area.rect.x + 1;
|
pos_x_ = param.game.play_area.rect.x + 1;
|
||||||
}
|
}
|
||||||
else if ((posX + width) > playArea->w)
|
else if ((pos_x_ + width_) > play_area_->w)
|
||||||
{
|
{
|
||||||
posX = float(playArea->w - width - 1);
|
pos_x_ = float(play_area_->w - width_ - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Posición X,Y del sprite
|
// Posición X,Y del sprite
|
||||||
sprite->setPosX(int(posX));
|
sprite_->setPosX(int(pos_x_));
|
||||||
sprite->setPosY(int(posY));
|
sprite_->setPosY(int(pos_y_));
|
||||||
|
|
||||||
// Alinea el circulo de colisión con el objeto
|
// Alinea el circulo de colisión con el objeto
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
@@ -68,15 +68,15 @@ void Item::allignTo(int x)
|
|||||||
// Pinta el objeto en la pantalla
|
// Pinta el objeto en la pantalla
|
||||||
void Item::render()
|
void Item::render()
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (enabled_)
|
||||||
{
|
{
|
||||||
if (timeToLive > 200)
|
if (time_to_live_ > 200)
|
||||||
{
|
{
|
||||||
sprite->render();
|
sprite_->render();
|
||||||
}
|
}
|
||||||
else if (timeToLive % 20 > 10)
|
else if (time_to_live_ % 20 > 10)
|
||||||
{
|
{
|
||||||
sprite->render();
|
sprite_->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,68 +84,68 @@ void Item::render()
|
|||||||
// Actualiza la posición y estados del objeto
|
// Actualiza la posición y estados del objeto
|
||||||
void Item::move()
|
void Item::move()
|
||||||
{
|
{
|
||||||
floorCollision = false;
|
floor_collision_ = false;
|
||||||
|
|
||||||
// Calcula la nueva posición
|
// Calcula la nueva posición
|
||||||
posX += velX;
|
pos_x_ += vel_x_;
|
||||||
posY += velY;
|
pos_y_ += vel_y_;
|
||||||
|
|
||||||
// Aplica las aceleraciones a la velocidad
|
// Aplica las aceleraciones a la velocidad
|
||||||
velX += accelX;
|
vel_x_ += accel_x_;
|
||||||
velY += accelY;
|
vel_y_ += accel_y_;
|
||||||
|
|
||||||
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
|
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
|
||||||
if ((posX < param.game.play_area.rect.x) || (posX + width > playArea->w))
|
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ + width_ > play_area_->w))
|
||||||
{
|
{
|
||||||
// Corregir posición
|
// Corregir posición
|
||||||
posX -= velX;
|
pos_x_ -= vel_x_;
|
||||||
|
|
||||||
// Invertir sentido
|
// Invertir sentido
|
||||||
velX = -velX;
|
vel_x_ = -vel_x_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si se sale por arriba rebota (excepto la maquina de café)
|
// Si se sale por arriba rebota (excepto la maquina de café)
|
||||||
if ((posY < param.game.play_area.rect.y) && !(kind == ITEM_COFFEE_MACHINE))
|
if ((pos_y_ < param.game.play_area.rect.y) && !(kind_ == ITEM_COFFEE_MACHINE))
|
||||||
{
|
{
|
||||||
// Corrige
|
// Corrige
|
||||||
posY = param.game.play_area.rect.y;
|
pos_y_ = param.game.play_area.rect.y;
|
||||||
|
|
||||||
// Invierte el sentido
|
// Invierte el sentido
|
||||||
velY = -velY;
|
vel_y_ = -vel_y_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si el objeto se sale por la parte inferior
|
// Si el objeto se sale por la parte inferior
|
||||||
if (posY + height > playArea->h)
|
if (pos_y_ + height_ > play_area_->h)
|
||||||
{
|
{
|
||||||
// Detiene el objeto
|
// Detiene el objeto
|
||||||
velY = 0;
|
vel_y_ = 0;
|
||||||
velX = 0;
|
vel_x_ = 0;
|
||||||
accelX = 0;
|
accel_x_ = 0;
|
||||||
accelY = 0;
|
accel_y_ = 0;
|
||||||
posY = playArea->h - height;
|
pos_y_ = play_area_->h - height_;
|
||||||
if (kind == ITEM_COFFEE_MACHINE)
|
if (kind_ == ITEM_COFFEE_MACHINE)
|
||||||
{
|
{
|
||||||
floorCollision = true;
|
floor_collision_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la posición del sprite
|
// Actualiza la posición del sprite
|
||||||
sprite->setPosX(int(posX));
|
sprite_->setPosX(int(pos_x_));
|
||||||
sprite->setPosY(int(posY));
|
sprite_->setPosY(int(pos_y_));
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pone a cero todos los valores del objeto
|
// Pone a cero todos los valores del objeto
|
||||||
void Item::disable()
|
void Item::disable()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el objeto a su posicion, animación y controla los contadores
|
// Actualiza el objeto a su posicion, animación y controla los contadores
|
||||||
void Item::update()
|
void Item::update()
|
||||||
{
|
{
|
||||||
move();
|
move();
|
||||||
sprite->animate();
|
sprite_->animate();
|
||||||
updateTimeToLive();
|
updateTimeToLive();
|
||||||
checkTimeToLive();
|
checkTimeToLive();
|
||||||
}
|
}
|
||||||
@@ -153,70 +153,70 @@ void Item::update()
|
|||||||
// Actualiza el contador
|
// Actualiza el contador
|
||||||
void Item::updateTimeToLive()
|
void Item::updateTimeToLive()
|
||||||
{
|
{
|
||||||
if (timeToLive > 0)
|
if (time_to_live_ > 0)
|
||||||
{
|
{
|
||||||
timeToLive--;
|
time_to_live_--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si el objeto sigue vivo
|
// Comprueba si el objeto sigue vivo
|
||||||
void Item::checkTimeToLive()
|
void Item::checkTimeToLive()
|
||||||
{
|
{
|
||||||
if (timeToLive == 0)
|
if (time_to_live_ == 0)
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
float Item::getPosX()
|
float Item::getPosX()
|
||||||
{
|
{
|
||||||
return posX;
|
return pos_x_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
float Item::getPosY()
|
float Item::getPosY()
|
||||||
{
|
{
|
||||||
return posY;
|
return pos_y_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
int Item::getWidth()
|
int Item::getWidth()
|
||||||
{
|
{
|
||||||
return width;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
int Item::getHeight()
|
int Item::getHeight()
|
||||||
{
|
{
|
||||||
return height;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
int Item::getClass()
|
int Item::getClass()
|
||||||
{
|
{
|
||||||
return kind;
|
return kind_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el valor de la variable
|
// Obtiene el valor de la variable
|
||||||
bool Item::isEnabled()
|
bool Item::isEnabled()
|
||||||
{
|
{
|
||||||
return enabled;
|
return enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el circulo de colisión
|
// Obtiene el circulo de colisión
|
||||||
Circle &Item::getCollider()
|
Circle &Item::getCollider()
|
||||||
{
|
{
|
||||||
return collider;
|
return collider_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alinea el circulo de colisión con la posición del objeto
|
// Alinea el circulo de colisión con la posición del objeto
|
||||||
void Item::shiftColliders()
|
void Item::shiftColliders()
|
||||||
{
|
{
|
||||||
collider.x = int(posX + (width / 2));
|
collider_.x = int(pos_x_ + (width_ / 2));
|
||||||
collider.y = int(posY + (height / 2));
|
collider_.y = int(pos_y_ + (height_ / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Informa si el objeto ha colisionado con el suelo
|
// Informa si el objeto ha colisionado con el suelo
|
||||||
bool Item::isOnFloor()
|
bool Item::isOnFloor()
|
||||||
{
|
{
|
||||||
return floorCollision;
|
return floor_collision_;
|
||||||
}
|
}
|
||||||
@@ -10,35 +10,36 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
// Tipos de objetos
|
// Tipos de objetos
|
||||||
#define ITEM_POINTS_1_DISK 1
|
constexpr int ITEM_POINTS_1_DISK = 1;
|
||||||
#define ITEM_POINTS_2_GAVINA 2
|
constexpr int ITEM_POINTS_2_GAVINA = 2;
|
||||||
#define ITEM_POINTS_3_PACMAR 3
|
constexpr int ITEM_POINTS_3_PACMAR = 3;
|
||||||
#define ITEM_CLOCK 4
|
constexpr int ITEM_CLOCK = 4;
|
||||||
#define ITEM_COFFEE 5
|
constexpr int ITEM_COFFEE = 5;
|
||||||
#define ITEM_COFFEE_MACHINE 6
|
constexpr int ITEM_COFFEE_MACHINE = 6;
|
||||||
#define ITEM_NULL 7
|
constexpr int ITEM_NULL = 7;
|
||||||
|
|
||||||
// Clase Item
|
// Clase Item
|
||||||
class Item
|
class Item
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
std::unique_ptr<AnimatedSprite> sprite; // Sprite con los graficos del objeto
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los graficos del objeto
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
float posX; // Posición X del objeto
|
float pos_x_; // Posición X del objeto
|
||||||
float posY; // Posición Y del objeto
|
float pos_y_; // Posición Y del objeto
|
||||||
int width; // Ancho del objeto
|
int width_; // Ancho del objeto
|
||||||
int height; // Alto del objeto
|
int height_; // Alto del objeto
|
||||||
float velX; // Velocidad en el eje X
|
float vel_x_; // Velocidad en el eje X
|
||||||
float velY; // Velocidad en el eje Y
|
float vel_y_; // Velocidad en el eje Y
|
||||||
float accelX; // Aceleración en el eje X
|
float accel_x_; // Aceleración en el eje X
|
||||||
float accelY; // Aceleración en el eje Y
|
float accel_y_; // Aceleración en el eje Y
|
||||||
bool floorCollision; // Indica si el objeto colisiona con el suelo
|
bool floor_collision_; // Indica si el objeto colisiona con el suelo
|
||||||
int kind; // Especifica el tipo de objeto que es
|
int kind_; // Especifica el tipo de objeto que es
|
||||||
bool enabled; // Especifica si el objeto está habilitado
|
bool enabled_; // Especifica si el objeto está habilitado
|
||||||
Circle collider; // Circulo de colisión del objeto
|
Circle collider_; // Circulo de colisión del objeto
|
||||||
SDL_Rect *playArea; // Rectangulo con la zona de juego
|
SDL_Rect *play_area_; // Rectangulo con la zona de juego
|
||||||
|
Uint16 time_to_live_; // Temporizador con el tiempo que el objeto está presente
|
||||||
|
|
||||||
// Alinea el circulo de colisión con la posición del objeto
|
// Alinea el circulo de colisión con la posición del objeto
|
||||||
void shiftColliders();
|
void shiftColliders();
|
||||||
@@ -46,11 +47,15 @@ private:
|
|||||||
// Actualiza la posición y estados del objeto
|
// Actualiza la posición y estados del objeto
|
||||||
void move();
|
void move();
|
||||||
|
|
||||||
public:
|
// Actualiza el contador
|
||||||
Uint16 timeToLive; // Temporizador con el tiempo que el objeto está presente
|
void updateTimeToLive();
|
||||||
|
|
||||||
|
// Comprueba si el objeto sigue vivo
|
||||||
|
void checkTimeToLive();
|
||||||
|
|
||||||
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
Item(int kind, float x, float y, SDL_Rect *playArea, std::shared_ptr<Texture> texture, std::vector<std::string> *animation);
|
Item(int kind, float x, float y, SDL_Rect *play_area, std::shared_ptr<Texture> texture, std::vector<std::string> *animation);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Item() = default;
|
~Item() = default;
|
||||||
@@ -67,12 +72,6 @@ public:
|
|||||||
// Actualiza al objeto a su posicion, animación y controla los contadores
|
// Actualiza al objeto a su posicion, animación y controla los contadores
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
// Actualiza el contador
|
|
||||||
void updateTimeToLive();
|
|
||||||
|
|
||||||
// Comprueba si el objeto sigue vivo
|
|
||||||
void checkTimeToLive();
|
|
||||||
|
|
||||||
// Obtiene del valor de la variable
|
// Obtiene del valor de la variable
|
||||||
float getPosX();
|
float getPosX();
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ namespace lang
|
|||||||
std::vector<std::string> texts; // Vector con los textos
|
std::vector<std::string> texts; // Vector con los textos
|
||||||
|
|
||||||
// Inicializa los textos del juego en el idioma seleccionado
|
// Inicializa los textos del juego en el idioma seleccionado
|
||||||
bool loadFromFile(std::string filePath)
|
bool loadFromFile(std::string file_path)
|
||||||
{
|
{
|
||||||
texts.clear();
|
texts.clear();
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
std::ifstream rfile(filePath);
|
std::ifstream rfile(file_path);
|
||||||
if (rfile.is_open() && rfile.good())
|
if (rfile.is_open() && rfile.good())
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace lang
|
namespace lang
|
||||||
{
|
{
|
||||||
enum lang_e
|
enum class Code : int
|
||||||
{
|
{
|
||||||
es_ES = 0,
|
es_ES = 0,
|
||||||
ba_BA = 1,
|
ba_BA = 1,
|
||||||
@@ -12,7 +12,7 @@ namespace lang
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Inicializa los textos del juego en el idioma seleccionado
|
// Inicializa los textos del juego en el idioma seleccionado
|
||||||
bool loadFromFile(std::string filePath);
|
bool loadFromFile(std::string file_path);
|
||||||
|
|
||||||
// Obtiene la cadena de texto del indice
|
// Obtiene la cadena de texto del indice
|
||||||
std::string getText(int index);
|
std::string getText(int index);
|
||||||
|
|||||||
104
source/logo.cpp
104
source/logo.cpp
@@ -20,54 +20,48 @@ Logo::Logo()
|
|||||||
SDL_Renderer *renderer = Screen::get()->getRenderer();
|
SDL_Renderer *renderer = Screen::get()->getRenderer();
|
||||||
|
|
||||||
// Reserva memoria para los punteros
|
// Reserva memoria para los punteros
|
||||||
jailTexture = std::make_shared<Texture>(renderer, Asset::get()->get("logo_jailgames.png"));
|
jail_texture_ = std::make_shared<Texture>(renderer, Asset::get()->get("logo_jailgames.png"));
|
||||||
sinceTexture = std::make_shared<Texture>(renderer, Asset::get()->get("logo_since_1998.png"));
|
since_texture_ = std::make_shared<Texture>(renderer, Asset::get()->get("logo_since_1998.png"));
|
||||||
sinceSprite = std::make_unique<Sprite>((param.game.width - sinceTexture->getWidth()) / 2, 83 + jailTexture->getHeight() + 5, sinceTexture->getWidth(), sinceTexture->getHeight(), sinceTexture);
|
since_sprite_ = std::make_unique<Sprite>((param.game.width - since_texture_->getWidth()) / 2, 83 + jail_texture_->getHeight() + 5, since_texture_->getWidth(), since_texture_->getHeight(), since_texture_);
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
counter = 0;
|
counter_ = 0;
|
||||||
section::name = section::Name::LOGO;
|
section::name = section::Name::LOGO;
|
||||||
ticks = 0;
|
ticks_ = 0;
|
||||||
ticksSpeed = 15;
|
dest_.x = param.game.game_area.center_x - jail_texture_->getWidth() / 2;
|
||||||
showSinceSprite_cm = 70;
|
dest_.y = param.game.game_area.center_y - jail_texture_->getHeight() / 2;
|
||||||
initFade_cm = 300;
|
since_sprite_->setPosY(dest_.y + jail_texture_->getHeight() + 5);
|
||||||
endLogo_cm = 400;
|
since_sprite_->setSpriteClip(0, 0, since_texture_->getWidth(), since_texture_->getHeight());
|
||||||
postLogoDuration = 20;
|
since_sprite_->setEnabled(false);
|
||||||
speed = 8;
|
since_texture_->setColor(0x00, 0x00, 0x00); // Esto en linux no hace nada ??
|
||||||
dest.x = param.game.game_area.center_x - jailTexture->getWidth() / 2;
|
|
||||||
dest.y = param.game.game_area.center_y - jailTexture->getHeight() / 2;
|
|
||||||
sinceSprite->setPosY(dest.y + jailTexture->getHeight() + 5);
|
|
||||||
sinceSprite->setSpriteClip(0, 0, sinceTexture->getWidth(), sinceTexture->getHeight());
|
|
||||||
sinceSprite->setEnabled(false);
|
|
||||||
sinceTexture->setColor(0x00, 0x00, 0x00); // Esto en linux no hace nada ??
|
|
||||||
|
|
||||||
// Crea los sprites de cada linea
|
// Crea los sprites de cada linea
|
||||||
for (int i = 0; i < jailTexture->getHeight(); ++i)
|
for (int i = 0; i < jail_texture_->getHeight(); ++i)
|
||||||
{
|
{
|
||||||
auto temp = std::make_unique<Sprite>(0, i, jailTexture->getWidth(), 1, jailTexture);
|
auto temp = std::make_unique<Sprite>(0, i, jail_texture_->getWidth(), 1, jail_texture_);
|
||||||
temp->setSpriteClip(0, i, jailTexture->getWidth(), 1);
|
temp->setSpriteClip(0, i, jail_texture_->getWidth(), 1);
|
||||||
const int posX = (i % 2 == 0) ? param.game.width + (i * 3) : -jailTexture->getWidth() - (i * 3);
|
const int posX = (i % 2 == 0) ? param.game.width + (i * 3) : -jail_texture_->getWidth() - (i * 3);
|
||||||
temp->setPosX(posX);
|
temp->setPosX(posX);
|
||||||
temp->setPosY(dest.y + i);
|
temp->setPosY(dest_.y + i);
|
||||||
jailSprite.push_back(std::move(temp));
|
jail_sprite_.push_back(std::move(temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa el vector de colores
|
// Inicializa el vector de colores
|
||||||
color.push_back({0x00, 0x00, 0x00}); // Black
|
color_.push_back({0x00, 0x00, 0x00}); // Black
|
||||||
color.push_back({0x00, 0x00, 0xd8}); // Blue
|
color_.push_back({0x00, 0x00, 0xd8}); // Blue
|
||||||
color.push_back({0xd8, 0x00, 0x00}); // Red
|
color_.push_back({0xd8, 0x00, 0x00}); // Red
|
||||||
color.push_back({0xd8, 0x00, 0xd8}); // Magenta
|
color_.push_back({0xd8, 0x00, 0xd8}); // Magenta
|
||||||
color.push_back({0x00, 0xd8, 0x00}); // Green
|
color_.push_back({0x00, 0xd8, 0x00}); // Green
|
||||||
color.push_back({0x00, 0xd8, 0xd8}); // Cyan
|
color_.push_back({0x00, 0xd8, 0xd8}); // Cyan
|
||||||
color.push_back({0xd8, 0xd8, 0x00}); // Yellow
|
color_.push_back({0xd8, 0xd8, 0x00}); // Yellow
|
||||||
color.push_back({0xFF, 0xFF, 0xFF}); // Bright white
|
color_.push_back({0xFF, 0xFF, 0xFF}); // Bright white
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recarga todas las texturas
|
// Recarga todas las texturas
|
||||||
void Logo::reloadTextures()
|
void Logo::reloadTextures()
|
||||||
{
|
{
|
||||||
jailTexture->reLoad();
|
jail_texture_->reLoad();
|
||||||
sinceTexture->reLoad();
|
since_texture_->reLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba el manejador de eventos
|
// Comprueba el manejador de eventos
|
||||||
@@ -117,26 +111,26 @@ void Logo::checkInput()
|
|||||||
// Gestiona el logo de JAILGAME
|
// Gestiona el logo de JAILGAME
|
||||||
void Logo::updateJAILGAMES()
|
void Logo::updateJAILGAMES()
|
||||||
{
|
{
|
||||||
if (counter > 30)
|
if (counter_ > 30)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)jailSprite.size(); ++i)
|
for (int i = 0; i < (int)jail_sprite_.size(); ++i)
|
||||||
{
|
{
|
||||||
if (jailSprite[i]->getPosX() != dest.x)
|
if (jail_sprite_[i]->getPosX() != dest_.x)
|
||||||
{
|
{
|
||||||
if (i % 2 == 0)
|
if (i % 2 == 0)
|
||||||
{
|
{
|
||||||
jailSprite[i]->incPosX(-speed);
|
jail_sprite_[i]->incPosX(-SPEED);
|
||||||
if (jailSprite[i]->getPosX() < dest.x)
|
if (jail_sprite_[i]->getPosX() < dest_.x)
|
||||||
{
|
{
|
||||||
jailSprite[i]->setPosX(dest.x);
|
jail_sprite_[i]->setPosX(dest_.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jailSprite[i]->incPosX(speed);
|
jail_sprite_[i]->incPosX(SPEED);
|
||||||
if (jailSprite[i]->getPosX() > dest.x)
|
if (jail_sprite_[i]->getPosX() > dest_.x)
|
||||||
{
|
{
|
||||||
jailSprite[i]->setPosX(dest.x);
|
jail_sprite_[i]->setPosX(dest_.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,19 +146,19 @@ void Logo::updateTextureColors()
|
|||||||
// Manejo de 'sinceTexture'
|
// Manejo de 'sinceTexture'
|
||||||
for (int i = 0; i <= 7; ++i)
|
for (int i = 0; i <= 7; ++i)
|
||||||
{
|
{
|
||||||
if (counter == showSinceSprite_cm + inc * i)
|
if (counter_ == SHOW_SINCE_SPRITE_COUNTER_MARK + inc * i)
|
||||||
{
|
{
|
||||||
sinceTexture->setColor(color[i].r, color[i].g, color[i].b);
|
since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manejo de 'jailTexture' y 'sinceTexture' en el fade
|
// Manejo de 'jailTexture' y 'sinceTexture' en el fade
|
||||||
for (int i = 0; i <= 6; ++i)
|
for (int i = 0; i <= 6; ++i)
|
||||||
{
|
{
|
||||||
if (counter == initFade_cm + inc * i)
|
if (counter_ == INIT_FADE_COUNTER_MARK + inc * i)
|
||||||
{
|
{
|
||||||
jailTexture->setColor(color[6 - i].r, color[6 - i].g, color[6 - i].b);
|
jail_texture_->setColor(color_[6 - i].r, color_[6 - i].g, color_[6 - i].b);
|
||||||
sinceTexture->setColor(color[6 - i].r, color[6 - i].g, color[6 - i].b);
|
since_texture_->setColor(color_[6 - i].r, color_[6 - i].g, color_[6 - i].b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,10 +167,10 @@ void Logo::updateTextureColors()
|
|||||||
void Logo::update()
|
void Logo::update()
|
||||||
{
|
{
|
||||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||||
if (SDL_GetTicks() - ticks > ticksSpeed)
|
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
|
||||||
{
|
{
|
||||||
// Actualiza el contador de ticks
|
// Actualiza el contador de ticks
|
||||||
ticks = SDL_GetTicks();
|
ticks_ = SDL_GetTicks();
|
||||||
|
|
||||||
// Actualiza el objeto screen
|
// Actualiza el objeto screen
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
@@ -191,18 +185,18 @@ void Logo::update()
|
|||||||
updateTextureColors();
|
updateTextureColors();
|
||||||
|
|
||||||
// Gestiona el contador y sus eventos
|
// Gestiona el contador y sus eventos
|
||||||
counter++;
|
counter_++;
|
||||||
|
|
||||||
// Comprueba si ha terminado el logo
|
// Comprueba si ha terminado el logo
|
||||||
if (counter == endLogo_cm + postLogoDuration)
|
if (counter_ == END_LOGO_COUNTER_MARK + POST_LOGO_DURATION)
|
||||||
{
|
{
|
||||||
section::name = section::Name::INTRO;
|
section::name = section::Name::INTRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si se ha de mostrar el sprite
|
// Comprueba si se ha de mostrar el sprite
|
||||||
else if (counter == showSinceSprite_cm)
|
else if (counter_ == SHOW_SINCE_SPRITE_COUNTER_MARK)
|
||||||
{
|
{
|
||||||
sinceSprite->setEnabled(true);
|
since_sprite_->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,11 +211,11 @@ void Logo::render()
|
|||||||
Screen::get()->clean();
|
Screen::get()->clean();
|
||||||
|
|
||||||
// Dibuja los sprites
|
// Dibuja los sprites
|
||||||
for (auto &sprite : jailSprite)
|
for (auto &sprite : jail_sprite_)
|
||||||
{
|
{
|
||||||
sprite->render();
|
sprite->render();
|
||||||
}
|
}
|
||||||
sinceSprite->render();
|
since_sprite_->render();
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
Screen::get()->blit();
|
Screen::get()->blit();
|
||||||
|
|||||||
@@ -21,23 +21,25 @@
|
|||||||
class Logo
|
class Logo
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
// Constantes
|
||||||
|
static constexpr Uint32 TICKS_SPEED = 15; // Velocidad a la que se repiten los bucles del programa
|
||||||
|
static constexpr int SHOW_SINCE_SPRITE_COUNTER_MARK = 70; // Tiempo del contador en el que empieza a verse el sprite de "SINCE 1998"
|
||||||
|
static constexpr int INIT_FADE_COUNTER_MARK = 300; // Tiempo del contador cuando inicia el fade a negro
|
||||||
|
static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo
|
||||||
|
static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al maximo
|
||||||
|
static constexpr int SPEED = 8; // Velocidad de desplazamiento de cada linea
|
||||||
|
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
std::shared_ptr<Texture> sinceTexture; // Textura con los graficos "Since 1998"
|
std::shared_ptr<Texture> since_texture_; // Textura con los graficos "Since 1998"
|
||||||
std::unique_ptr<Sprite> sinceSprite; // Sprite para manejar la sinceTexture
|
std::unique_ptr<Sprite> since_sprite_; // Sprite para manejar la sinceTexture
|
||||||
std::shared_ptr<Texture> jailTexture; // Textura con los graficos "JAILGAMES"
|
std::shared_ptr<Texture> jail_texture_; // Textura con los graficos "JAILGAMES"
|
||||||
std::vector<std::unique_ptr<Sprite>> jailSprite; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES
|
std::vector<std::unique_ptr<Sprite>> jail_sprite_; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
std::vector<Color> color; // Vector con los colores para el fade
|
std::vector<Color> color_; // Vector con los colores para el fade
|
||||||
int counter; // Contador
|
int counter_; // Contador
|
||||||
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
|
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||||
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
SDL_Point dest_; // Posición X donde dibujar el logo
|
||||||
int showSinceSprite_cm; // Tiempo del contador en el que empieza a verse el sprite de "SINCE 1998"
|
|
||||||
int initFade_cm; // Tiempo del contador cuando inicia el fade a negro
|
|
||||||
int endLogo_cm; // Tiempo del contador para terminar el logo
|
|
||||||
int postLogoDuration; // Tiempo que dura el logo con el fade al maximo
|
|
||||||
int speed; // Velocidad de desplazamiento de cada linea
|
|
||||||
SDL_Point dest; // Posición X donde dibujar el logo
|
|
||||||
|
|
||||||
// Actualiza las variables
|
// Actualiza las variables
|
||||||
void update();
|
void update();
|
||||||
|
|||||||
@@ -8,40 +8,40 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ManageHiScoreTable::ManageHiScoreTable(std::vector<HiScoreEntry> *table)
|
ManageHiScoreTable::ManageHiScoreTable(std::vector<HiScoreEntry> *table)
|
||||||
: table(table) {}
|
: table_(table) {}
|
||||||
|
|
||||||
// Resetea la tabla a los valores por defecto
|
// Resetea la tabla a los valores por defecto
|
||||||
void ManageHiScoreTable::clear()
|
void ManageHiScoreTable::clear()
|
||||||
{
|
{
|
||||||
// Limpia la tabla
|
// Limpia la tabla
|
||||||
table->clear();
|
table_->clear();
|
||||||
|
|
||||||
// Añade 10 entradas predefinidas
|
// Añade 10 entradas predefinidas
|
||||||
table->push_back({"Bry", 1000000});
|
table_->push_back({"Bry", 1000000});
|
||||||
table->push_back({"Usufondo", 500000});
|
table_->push_back({"Usufondo", 500000});
|
||||||
table->push_back({"G.Lucas", 100000});
|
table_->push_back({"G.Lucas", 100000});
|
||||||
table->push_back({"P.Delgat", 50000});
|
table_->push_back({"P.Delgat", 50000});
|
||||||
table->push_back({"P.Arrabalera", 10000});
|
table_->push_back({"P.Arrabalera", 10000});
|
||||||
table->push_back({"Pelechano", 5000});
|
table_->push_back({"Pelechano", 5000});
|
||||||
table->push_back({"Sahuquillo", 1000});
|
table_->push_back({"Sahuquillo", 1000});
|
||||||
table->push_back({"Bacteriol", 500});
|
table_->push_back({"Bacteriol", 500});
|
||||||
table->push_back({"Pepe", 200});
|
table_->push_back({"Pepe", 200});
|
||||||
table->push_back({"Rosita", 100});
|
table_->push_back({"Rosita", 100});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Añade un elemento a la tabla
|
// Añade un elemento a la tabla
|
||||||
void ManageHiScoreTable::add(HiScoreEntry entry)
|
void ManageHiScoreTable::add(HiScoreEntry entry)
|
||||||
{
|
{
|
||||||
// Añade la entrada a la tabla
|
// Añade la entrada a la tabla
|
||||||
table->push_back(entry);
|
table_->push_back(entry);
|
||||||
|
|
||||||
// Ordena la tabla
|
// Ordena la tabla
|
||||||
sort();
|
sort();
|
||||||
|
|
||||||
// Deja solo las 10 primeras entradas
|
// Deja solo las 10 primeras entradas
|
||||||
if ((int)table->size() > 10)
|
if (static_cast<int>(table_->size()) > 10)
|
||||||
{
|
{
|
||||||
table->resize(10);
|
table_->resize(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,30 +51,30 @@ void ManageHiScoreTable::sort()
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool operator()(HiScoreEntry a, HiScoreEntry b) const { return a.score > b.score; }
|
bool operator()(HiScoreEntry a, HiScoreEntry b) const { return a.score > b.score; }
|
||||||
} customLess;
|
} custom_less;
|
||||||
|
|
||||||
std::sort(table->begin(), table->end(), customLess);
|
std::sort(table_->begin(), table_->end(), custom_less);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga la tabla con los datos de un fichero
|
// Carga la tabla con los datos de un fichero
|
||||||
bool ManageHiScoreTable::loadFromFile(std::string filePath)
|
bool ManageHiScoreTable::loadFromFile(std::string file_path)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
bool success = true;
|
auto success = true;
|
||||||
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
|
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
|
||||||
SDL_RWops *file = SDL_RWFromFile(filePath.c_str(), "r+b");
|
auto file = SDL_RWFromFile(file_path.c_str(), "r+b");
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef VERBOSE
|
||||||
std::cout << "Reading file: " << filename.c_str() << std::endl;
|
std::cout << "Reading file: " << filename.c_str() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < (int)table->size(); ++i)
|
for (int i = 0; i < (int)table_->size(); ++i)
|
||||||
{
|
{
|
||||||
int nameSize = 0;
|
int nameSize = 0;
|
||||||
|
|
||||||
if (SDL_RWread(file, &table->at(i).score, sizeof(int), 1) == 0)
|
if (SDL_RWread(file, &table_->at(i).score, sizeof(int), 1) == 0)
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
@@ -96,7 +96,7 @@ bool ManageHiScoreTable::loadFromFile(std::string filePath)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
name[nameSize] = 0;
|
name[nameSize] = 0;
|
||||||
table->at(i).name = name;
|
table_->at(i).name = name;
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,24 +113,24 @@ bool ManageHiScoreTable::loadFromFile(std::string filePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Guarda la tabla en un fichero
|
// Guarda la tabla en un fichero
|
||||||
bool ManageHiScoreTable::saveToFile(std::string filePath)
|
bool ManageHiScoreTable::saveToFile(std::string file_path)
|
||||||
{
|
{
|
||||||
bool success = true;
|
auto success = true;
|
||||||
const std::string fileName = filePath.substr(filePath.find_last_of("\\/") + 1);
|
const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1);
|
||||||
SDL_RWops *file = SDL_RWFromFile(filePath.c_str(), "w+b");
|
auto file = SDL_RWFromFile(file_path.c_str(), "w+b");
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
// Guarda los datos
|
// Guarda los datos
|
||||||
for (int i = 0; i < (int)table->size(); ++i)
|
for (int i = 0; i < (int)table_->size(); ++i)
|
||||||
{
|
{
|
||||||
SDL_RWwrite(file, &table->at(i).score, sizeof(int), 1);
|
SDL_RWwrite(file, &table_->at(i).score, sizeof(int), 1);
|
||||||
const int nameSize = (int)table->at(i).name.size();
|
const int nameSize = (int)table_->at(i).name.size();
|
||||||
SDL_RWwrite(file, &nameSize, sizeof(int), 1);
|
SDL_RWwrite(file, &nameSize, sizeof(int), 1);
|
||||||
SDL_RWwrite(file, table->at(i).name.c_str(), nameSize, 1);
|
SDL_RWwrite(file, table_->at(i).name.c_str(), nameSize, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef VERBOSE
|
||||||
std::cout << "Writing file: " << fileName.c_str() << std::endl;
|
std::cout << "Writing file: " << fileName.c_str() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
// Cierra el fichero
|
// Cierra el fichero
|
||||||
@@ -138,7 +138,7 @@ bool ManageHiScoreTable::saveToFile(std::string filePath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef VERBOSE
|
||||||
std::cout << "Error: Unable to save " << fileName.c_str() << " file! " << SDL_GetError() << std::endl;
|
std::cout << "Error: Unable to save " << fileName.c_str() << " file! " << SDL_GetError() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class ManageHiScoreTable
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Variables
|
// Variables
|
||||||
std::vector<HiScoreEntry> *table; // Tabla con los records
|
std::vector<HiScoreEntry> *table_; // Tabla con los records
|
||||||
|
|
||||||
// Ordena la tabla
|
// Ordena la tabla
|
||||||
void sort();
|
void sort();
|
||||||
@@ -36,8 +36,8 @@ public:
|
|||||||
void add(HiScoreEntry entry);
|
void add(HiScoreEntry entry);
|
||||||
|
|
||||||
// Carga la tabla con los datos de un fichero
|
// Carga la tabla con los datos de un fichero
|
||||||
bool loadFromFile(std::string filePath);
|
bool loadFromFile(std::string file_path);
|
||||||
|
|
||||||
// Guarda la tabla en un fichero
|
// Guarda la tabla en un fichero
|
||||||
bool saveToFile(std::string filePath);
|
bool saveToFile(std::string file_path);
|
||||||
};
|
};
|
||||||
@@ -39,7 +39,7 @@ void initOptions()
|
|||||||
|
|
||||||
// Opciones de juego
|
// Opciones de juego
|
||||||
options.game.difficulty = GameDifficulty::NORMAL;
|
options.game.difficulty = GameDifficulty::NORMAL;
|
||||||
options.game.language = lang::ba_BA;
|
options.game.language = lang::Code::ba_BA;
|
||||||
options.game.autofire = true;
|
options.game.autofire = true;
|
||||||
|
|
||||||
// Opciones de control
|
// Opciones de control
|
||||||
@@ -139,9 +139,9 @@ bool loadOptionsFile(std::string file_path)
|
|||||||
options.video.window.size = 3;
|
options.video.window.size = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.game.language < 0 || options.game.language > 2)
|
if (options.game.language != lang::Code::en_UK && options.game.language != lang::Code::ba_BA && options.game.language != lang::Code::es_ES)
|
||||||
{
|
{
|
||||||
options.game.language = lang::en_UK;
|
options.game.language = lang::Code::en_UK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -207,7 +207,7 @@ bool saveOptionsFile(std::string file_path)
|
|||||||
file << "## game.difficulty [" << value_difficulty_easy << ": easy, " << value_difficulty_normal << ": normal, " << value_difficulty_hard << ": hard]\n";
|
file << "## game.difficulty [" << value_difficulty_easy << ": easy, " << value_difficulty_normal << ": normal, " << value_difficulty_hard << ": hard]\n";
|
||||||
file << "\n";
|
file << "\n";
|
||||||
|
|
||||||
file << "game.language=" + std::to_string(options.game.language) + "\n";
|
file << "game.language=" + std::to_string(static_cast<int>(options.game.language)) + "\n";
|
||||||
file << "game.difficulty=" + std::to_string(static_cast<int>(options.game.difficulty)) + "\n";
|
file << "game.difficulty=" + std::to_string(static_cast<int>(options.game.difficulty)) + "\n";
|
||||||
file << "game.autofire=" + boolToString(options.game.autofire) + "\n";
|
file << "game.autofire=" + boolToString(options.game.autofire) + "\n";
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ bool setOptions(std::string var, std::string value)
|
|||||||
// Opciones de juego
|
// Opciones de juego
|
||||||
else if (var == "game.language")
|
else if (var == "game.language")
|
||||||
{
|
{
|
||||||
options.game.language = std::stoi(value);
|
options.game.language = static_cast<lang::Code>(std::stoi(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (var == "game.difficulty")
|
else if (var == "game.difficulty")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
@@ -48,6 +48,9 @@ LICENSE
|
|||||||
|
|
||||||
RECENT REVISION HISTORY:
|
RECENT REVISION HISTORY:
|
||||||
|
|
||||||
|
2.30 (2024-05-31) avoid erroneous gcc warning
|
||||||
|
2.29 (2023-05-xx) optimizations
|
||||||
|
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
|
||||||
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
||||||
2.26 (2020-07-13) many minor fixes
|
2.26 (2020-07-13) many minor fixes
|
||||||
2.25 (2020-02-02) fix warnings
|
2.25 (2020-02-02) fix warnings
|
||||||
@@ -108,7 +111,7 @@ RECENT REVISION HISTORY:
|
|||||||
Cass Everitt Ryamond Barbiero github:grim210
|
Cass Everitt Ryamond Barbiero github:grim210
|
||||||
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
|
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
|
||||||
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
|
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
|
||||||
Josh Tobin Matthew Gregan github:poppolopoppo
|
Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
|
||||||
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
|
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
|
||||||
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
|
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
|
||||||
Brad Weinberger Matvey Cherevko github:mosra
|
Brad Weinberger Matvey Cherevko github:mosra
|
||||||
@@ -140,7 +143,7 @@ RECENT REVISION HISTORY:
|
|||||||
// // ... x = width, y = height, n = # 8-bit components per pixel ...
|
// // ... x = width, y = height, n = # 8-bit components per pixel ...
|
||||||
// // ... replace '0' with '1'..'4' to force that many components per pixel
|
// // ... replace '0' with '1'..'4' to force that many components per pixel
|
||||||
// // ... but 'n' will always be the number that it would have been if you said 0
|
// // ... but 'n' will always be the number that it would have been if you said 0
|
||||||
// stbi_image_free(data)
|
// stbi_image_free(data);
|
||||||
//
|
//
|
||||||
// Standard parameters:
|
// Standard parameters:
|
||||||
// int *x -- outputs image width in pixels
|
// int *x -- outputs image width in pixels
|
||||||
@@ -635,7 +638,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) || defined(__SYMBIAN32__)
|
||||||
typedef unsigned short stbi__uint16;
|
typedef unsigned short stbi__uint16;
|
||||||
typedef signed short stbi__int16;
|
typedef signed short stbi__int16;
|
||||||
typedef unsigned int stbi__uint32;
|
typedef unsigned int stbi__uint32;
|
||||||
@@ -1063,6 +1066,23 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
|
||||||
|
static int stbi__addints_valid(int a, int b)
|
||||||
|
{
|
||||||
|
if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
|
||||||
|
if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
|
||||||
|
return a <= INT_MAX - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
|
||||||
|
static int stbi__mul2shorts_valid(int a, int b)
|
||||||
|
{
|
||||||
|
if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
|
||||||
|
if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
|
||||||
|
if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
|
||||||
|
return a >= SHRT_MIN / b;
|
||||||
|
}
|
||||||
|
|
||||||
// stbi__err - error
|
// stbi__err - error
|
||||||
// stbi__errpf - error returning pointer to float
|
// stbi__errpf - error returning pointer to float
|
||||||
// stbi__errpuc - error returning pointer to unsigned char
|
// stbi__errpuc - error returning pointer to unsigned char
|
||||||
@@ -1985,9 +2005,12 @@ static int stbi__build_huffman(stbi__huffman *h, int *count)
|
|||||||
int i,j,k=0;
|
int i,j,k=0;
|
||||||
unsigned int code;
|
unsigned int code;
|
||||||
// build size list for each symbol (from JPEG spec)
|
// build size list for each symbol (from JPEG spec)
|
||||||
for (i=0; i < 16; ++i)
|
for (i=0; i < 16; ++i) {
|
||||||
for (j=0; j < count[i]; ++j)
|
for (j=0; j < count[i]; ++j) {
|
||||||
h->size[k++] = (stbi_uc) (i+1);
|
h->size[k++] = (stbi_uc) (i+1);
|
||||||
|
if(k >= 257) return stbi__err("bad size list","Corrupt JPEG");
|
||||||
|
}
|
||||||
|
}
|
||||||
h->size[k] = 0;
|
h->size[k] = 0;
|
||||||
|
|
||||||
// compute actual symbols (from jpeg spec)
|
// compute actual symbols (from jpeg spec)
|
||||||
@@ -2112,6 +2135,8 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
|
|||||||
|
|
||||||
// convert the huffman code to the symbol id
|
// convert the huffman code to the symbol id
|
||||||
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
|
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
|
||||||
|
if(c < 0 || c >= 256) // symbol id out of bounds!
|
||||||
|
return -1;
|
||||||
STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
|
STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
|
||||||
|
|
||||||
// convert the id to a symbol
|
// convert the id to a symbol
|
||||||
@@ -2130,6 +2155,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
|
|||||||
unsigned int k;
|
unsigned int k;
|
||||||
int sgn;
|
int sgn;
|
||||||
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
|
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
|
||||||
|
if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
|
||||||
|
|
||||||
sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
|
sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
|
||||||
k = stbi_lrot(j->code_buffer, n);
|
k = stbi_lrot(j->code_buffer, n);
|
||||||
@@ -2144,6 +2170,7 @@ stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
|
|||||||
{
|
{
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
|
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
|
||||||
|
if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
|
||||||
k = stbi_lrot(j->code_buffer, n);
|
k = stbi_lrot(j->code_buffer, n);
|
||||||
j->code_buffer = k & ~stbi__bmask[n];
|
j->code_buffer = k & ~stbi__bmask[n];
|
||||||
k &= stbi__bmask[n];
|
k &= stbi__bmask[n];
|
||||||
@@ -2155,6 +2182,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
|
|||||||
{
|
{
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
|
if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
|
||||||
|
if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing
|
||||||
k = j->code_buffer;
|
k = j->code_buffer;
|
||||||
j->code_buffer <<= 1;
|
j->code_buffer <<= 1;
|
||||||
--j->code_bits;
|
--j->code_bits;
|
||||||
@@ -2192,8 +2220,10 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
|
|||||||
memset(data,0,64*sizeof(data[0]));
|
memset(data,0,64*sizeof(data[0]));
|
||||||
|
|
||||||
diff = t ? stbi__extend_receive(j, t) : 0;
|
diff = t ? stbi__extend_receive(j, t) : 0;
|
||||||
|
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
|
||||||
dc = j->img_comp[b].dc_pred + diff;
|
dc = j->img_comp[b].dc_pred + diff;
|
||||||
j->img_comp[b].dc_pred = dc;
|
j->img_comp[b].dc_pred = dc;
|
||||||
|
if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||||
data[0] = (short) (dc * dequant[0]);
|
data[0] = (short) (dc * dequant[0]);
|
||||||
|
|
||||||
// decode AC components, see JPEG spec
|
// decode AC components, see JPEG spec
|
||||||
@@ -2207,6 +2237,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
|
|||||||
if (r) { // fast-AC path
|
if (r) { // fast-AC path
|
||||||
k += (r >> 4) & 15; // run
|
k += (r >> 4) & 15; // run
|
||||||
s = r & 15; // combined length
|
s = r & 15; // combined length
|
||||||
|
if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
|
||||||
j->code_buffer <<= s;
|
j->code_buffer <<= s;
|
||||||
j->code_bits -= s;
|
j->code_bits -= s;
|
||||||
// decode into unzigzag'd location
|
// decode into unzigzag'd location
|
||||||
@@ -2246,8 +2277,10 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
|
|||||||
if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||||
diff = t ? stbi__extend_receive(j, t) : 0;
|
diff = t ? stbi__extend_receive(j, t) : 0;
|
||||||
|
|
||||||
|
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
|
||||||
dc = j->img_comp[b].dc_pred + diff;
|
dc = j->img_comp[b].dc_pred + diff;
|
||||||
j->img_comp[b].dc_pred = dc;
|
j->img_comp[b].dc_pred = dc;
|
||||||
|
if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||||
data[0] = (short) (dc * (1 << j->succ_low));
|
data[0] = (short) (dc * (1 << j->succ_low));
|
||||||
} else {
|
} else {
|
||||||
// refinement scan for DC coefficient
|
// refinement scan for DC coefficient
|
||||||
@@ -2282,6 +2315,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
|||||||
if (r) { // fast-AC path
|
if (r) { // fast-AC path
|
||||||
k += (r >> 4) & 15; // run
|
k += (r >> 4) & 15; // run
|
||||||
s = r & 15; // combined length
|
s = r & 15; // combined length
|
||||||
|
if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
|
||||||
j->code_buffer <<= s;
|
j->code_buffer <<= s;
|
||||||
j->code_bits -= s;
|
j->code_bits -= s;
|
||||||
zig = stbi__jpeg_dezigzag[k++];
|
zig = stbi__jpeg_dezigzag[k++];
|
||||||
@@ -3102,6 +3136,7 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
|
|||||||
sizes[i] = stbi__get8(z->s);
|
sizes[i] = stbi__get8(z->s);
|
||||||
n += sizes[i];
|
n += sizes[i];
|
||||||
}
|
}
|
||||||
|
if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values!
|
||||||
L -= 17;
|
L -= 17;
|
||||||
if (tc == 0) {
|
if (tc == 0) {
|
||||||
if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
|
if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
|
||||||
@@ -3351,6 +3386,28 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
||||||
|
{
|
||||||
|
// some JPEGs have junk at end, skip over it but if we find what looks
|
||||||
|
// like a valid marker, resume there
|
||||||
|
while (!stbi__at_eof(j->s)) {
|
||||||
|
stbi_uc x = stbi__get8(j->s);
|
||||||
|
while (x == 0xff) { // might be a marker
|
||||||
|
if (stbi__at_eof(j->s)) return STBI__MARKER_none;
|
||||||
|
x = stbi__get8(j->s);
|
||||||
|
if (x != 0x00 && x != 0xff) {
|
||||||
|
// not a stuffed zero or lead-in to another marker, looks
|
||||||
|
// like an actual marker, return it
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
// stuffed zero has x=0 now which ends the loop, meaning we go
|
||||||
|
// back to regular scan loop.
|
||||||
|
// repeated 0xff keeps trying to read the next byte of the marker.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STBI__MARKER_none;
|
||||||
|
}
|
||||||
|
|
||||||
// decode image to YCbCr format
|
// decode image to YCbCr format
|
||||||
static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
||||||
{
|
{
|
||||||
@@ -3367,25 +3424,22 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
|||||||
if (!stbi__process_scan_header(j)) return 0;
|
if (!stbi__process_scan_header(j)) return 0;
|
||||||
if (!stbi__parse_entropy_coded_data(j)) return 0;
|
if (!stbi__parse_entropy_coded_data(j)) return 0;
|
||||||
if (j->marker == STBI__MARKER_none ) {
|
if (j->marker == STBI__MARKER_none ) {
|
||||||
// handle 0s at the end of image data from IP Kamera 9060
|
j->marker = stbi__skip_jpeg_junk_at_end(j);
|
||||||
while (!stbi__at_eof(j->s)) {
|
|
||||||
int x = stbi__get8(j->s);
|
|
||||||
if (x == 255) {
|
|
||||||
j->marker = stbi__get8(j->s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
|
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
|
||||||
}
|
}
|
||||||
|
m = stbi__get_marker(j);
|
||||||
|
if (STBI__RESTART(m))
|
||||||
|
m = stbi__get_marker(j);
|
||||||
} else if (stbi__DNL(m)) {
|
} else if (stbi__DNL(m)) {
|
||||||
int Ld = stbi__get16be(j->s);
|
int Ld = stbi__get16be(j->s);
|
||||||
stbi__uint32 NL = stbi__get16be(j->s);
|
stbi__uint32 NL = stbi__get16be(j->s);
|
||||||
if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
|
if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
|
||||||
if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
|
if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
|
||||||
} else {
|
|
||||||
if (!stbi__process_marker(j, m)) return 0;
|
|
||||||
}
|
|
||||||
m = stbi__get_marker(j);
|
m = stbi__get_marker(j);
|
||||||
|
} else {
|
||||||
|
if (!stbi__process_marker(j, m)) return 1;
|
||||||
|
m = stbi__get_marker(j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (j->progressive)
|
if (j->progressive)
|
||||||
stbi__jpeg_finish(j);
|
stbi__jpeg_finish(j);
|
||||||
@@ -3976,6 +4030,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
unsigned char* result;
|
unsigned char* result;
|
||||||
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
|
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
|
||||||
if (!j) return stbi__errpuc("outofmem", "Out of memory");
|
if (!j) return stbi__errpuc("outofmem", "Out of memory");
|
||||||
|
memset(j, 0, sizeof(stbi__jpeg));
|
||||||
STBI_NOTUSED(ri);
|
STBI_NOTUSED(ri);
|
||||||
j->s = s;
|
j->s = s;
|
||||||
stbi__setup_jpeg(j);
|
stbi__setup_jpeg(j);
|
||||||
@@ -3989,6 +4044,7 @@ static int stbi__jpeg_test(stbi__context *s)
|
|||||||
int r;
|
int r;
|
||||||
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
|
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
|
||||||
if (!j) return stbi__err("outofmem", "Out of memory");
|
if (!j) return stbi__err("outofmem", "Out of memory");
|
||||||
|
memset(j, 0, sizeof(stbi__jpeg));
|
||||||
j->s = s;
|
j->s = s;
|
||||||
stbi__setup_jpeg(j);
|
stbi__setup_jpeg(j);
|
||||||
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
|
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
|
||||||
@@ -4014,6 +4070,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
int result;
|
int result;
|
||||||
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
|
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
|
||||||
if (!j) return stbi__err("outofmem", "Out of memory");
|
if (!j) return stbi__err("outofmem", "Out of memory");
|
||||||
|
memset(j, 0, sizeof(stbi__jpeg));
|
||||||
j->s = s;
|
j->s = s;
|
||||||
result = stbi__jpeg_info_raw(j, x, y, comp);
|
result = stbi__jpeg_info_raw(j, x, y, comp);
|
||||||
STBI_FREE(j);
|
STBI_FREE(j);
|
||||||
@@ -4121,6 +4178,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
stbi_uc *zbuffer, *zbuffer_end;
|
stbi_uc *zbuffer, *zbuffer_end;
|
||||||
int num_bits;
|
int num_bits;
|
||||||
|
int hit_zeof_once;
|
||||||
stbi__uint32 code_buffer;
|
stbi__uint32 code_buffer;
|
||||||
|
|
||||||
char *zout;
|
char *zout;
|
||||||
@@ -4187,10 +4245,21 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
int b,s;
|
int b,s;
|
||||||
if (a->num_bits < 16) {
|
if (a->num_bits < 16) {
|
||||||
if (stbi__zeof(a)) {
|
if (stbi__zeof(a)) {
|
||||||
return -1; /* report error for unexpected end of data. */
|
if (!a->hit_zeof_once) {
|
||||||
|
// This is the first time we hit eof, insert 16 extra padding btis
|
||||||
|
// to allow us to keep going; if we actually consume any of them
|
||||||
|
// though, that is invalid data. This is caught later.
|
||||||
|
a->hit_zeof_once = 1;
|
||||||
|
a->num_bits += 16; // add 16 implicit zero bits
|
||||||
|
} else {
|
||||||
|
// We already inserted our extra 16 padding bits and are again
|
||||||
|
// out, this stream is actually prematurely terminated.
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
stbi__fill_bits(a);
|
stbi__fill_bits(a);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
||||||
if (b) {
|
if (b) {
|
||||||
s = b >> 9;
|
s = b >> 9;
|
||||||
@@ -4254,17 +4323,25 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|||||||
int len,dist;
|
int len,dist;
|
||||||
if (z == 256) {
|
if (z == 256) {
|
||||||
a->zout = zout;
|
a->zout = zout;
|
||||||
|
if (a->hit_zeof_once && a->num_bits < 16) {
|
||||||
|
// The first time we hit zeof, we inserted 16 extra zero bits into our bit
|
||||||
|
// buffer so the decoder can just do its speculative decoding. But if we
|
||||||
|
// actually consumed any of those bits (which is the case when num_bits < 16),
|
||||||
|
// the stream actually read past the end so it is malformed.
|
||||||
|
return stbi__err("unexpected end","Corrupt PNG");
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
|
||||||
z -= 257;
|
z -= 257;
|
||||||
len = stbi__zlength_base[z];
|
len = stbi__zlength_base[z];
|
||||||
if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
|
if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
|
||||||
z = stbi__zhuffman_decode(a, &a->z_distance);
|
z = stbi__zhuffman_decode(a, &a->z_distance);
|
||||||
if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
|
if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data
|
||||||
dist = stbi__zdist_base[z];
|
dist = stbi__zdist_base[z];
|
||||||
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
||||||
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
|
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
|
||||||
if (zout + len > a->zout_end) {
|
if (len > a->zout_end - zout) {
|
||||||
if (!stbi__zexpand(a, zout, len)) return 0;
|
if (!stbi__zexpand(a, zout, len)) return 0;
|
||||||
zout = a->zout;
|
zout = a->zout;
|
||||||
}
|
}
|
||||||
@@ -4408,6 +4485,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|||||||
if (!stbi__parse_zlib_header(a)) return 0;
|
if (!stbi__parse_zlib_header(a)) return 0;
|
||||||
a->num_bits = 0;
|
a->num_bits = 0;
|
||||||
a->code_buffer = 0;
|
a->code_buffer = 0;
|
||||||
|
a->hit_zeof_once = 0;
|
||||||
do {
|
do {
|
||||||
final = stbi__zreceive(a,1);
|
final = stbi__zreceive(a,1);
|
||||||
type = stbi__zreceive(a,2);
|
type = stbi__zreceive(a,2);
|
||||||
@@ -4563,9 +4641,8 @@ enum {
|
|||||||
STBI__F_up=2,
|
STBI__F_up=2,
|
||||||
STBI__F_avg=3,
|
STBI__F_avg=3,
|
||||||
STBI__F_paeth=4,
|
STBI__F_paeth=4,
|
||||||
// synthetic filters used for first scanline to avoid needing a dummy row of 0s
|
// synthetic filter used for first scanline to avoid needing a dummy row of 0s
|
||||||
STBI__F_avg_first,
|
STBI__F_avg_first
|
||||||
STBI__F_paeth_first
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static stbi_uc first_row_filter[5] =
|
static stbi_uc first_row_filter[5] =
|
||||||
@@ -4574,29 +4651,56 @@ static stbi_uc first_row_filter[5] =
|
|||||||
STBI__F_sub,
|
STBI__F_sub,
|
||||||
STBI__F_none,
|
STBI__F_none,
|
||||||
STBI__F_avg_first,
|
STBI__F_avg_first,
|
||||||
STBI__F_paeth_first
|
STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
|
||||||
};
|
};
|
||||||
|
|
||||||
static int stbi__paeth(int a, int b, int c)
|
static int stbi__paeth(int a, int b, int c)
|
||||||
{
|
{
|
||||||
int p = a + b - c;
|
// This formulation looks very different from the reference in the PNG spec, but is
|
||||||
int pa = abs(p-a);
|
// actually equivalent and has favorable data dependencies and admits straightforward
|
||||||
int pb = abs(p-b);
|
// generation of branch-free code, which helps performance significantly.
|
||||||
int pc = abs(p-c);
|
int thresh = c*3 - (a + b);
|
||||||
if (pa <= pb && pa <= pc) return a;
|
int lo = a < b ? a : b;
|
||||||
if (pb <= pc) return b;
|
int hi = a < b ? b : a;
|
||||||
return c;
|
int t0 = (hi <= thresh) ? lo : c;
|
||||||
|
int t1 = (thresh <= lo) ? hi : t0;
|
||||||
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
||||||
|
|
||||||
|
// adds an extra all-255 alpha channel
|
||||||
|
// dest == src is legal
|
||||||
|
// img_n must be 1 or 3
|
||||||
|
static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// must process data backwards since we allow dest==src
|
||||||
|
if (img_n == 1) {
|
||||||
|
for (i=x-1; i >= 0; --i) {
|
||||||
|
dest[i*2+1] = 255;
|
||||||
|
dest[i*2+0] = src[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
STBI_ASSERT(img_n == 3);
|
||||||
|
for (i=x-1; i >= 0; --i) {
|
||||||
|
dest[i*4+3] = 255;
|
||||||
|
dest[i*4+2] = src[i*3+2];
|
||||||
|
dest[i*4+1] = src[i*3+1];
|
||||||
|
dest[i*4+0] = src[i*3+0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create the png data from post-deflated data
|
// create the png data from post-deflated data
|
||||||
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
||||||
{
|
{
|
||||||
int bytes = (depth == 16? 2 : 1);
|
int bytes = (depth == 16 ? 2 : 1);
|
||||||
stbi__context *s = a->s;
|
stbi__context *s = a->s;
|
||||||
stbi__uint32 i,j,stride = x*out_n*bytes;
|
stbi__uint32 i,j,stride = x*out_n*bytes;
|
||||||
stbi__uint32 img_len, img_width_bytes;
|
stbi__uint32 img_len, img_width_bytes;
|
||||||
|
stbi_uc *filter_buf;
|
||||||
|
int all_ok = 1;
|
||||||
int k;
|
int k;
|
||||||
int img_n = s->img_n; // copy it into a local for later
|
int img_n = s->img_n; // copy it into a local for later
|
||||||
|
|
||||||
@@ -4608,8 +4712,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
||||||
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
||||||
|
|
||||||
|
// note: error exits here don't need to clean up a->out individually,
|
||||||
|
// stbi__do_png always does on error.
|
||||||
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
|
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
|
||||||
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
||||||
|
if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG");
|
||||||
img_len = (img_width_bytes + 1) * y;
|
img_len = (img_width_bytes + 1) * y;
|
||||||
|
|
||||||
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
||||||
@@ -4617,188 +4724,136 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
// so just check for raw_len < img_len always.
|
// so just check for raw_len < img_len always.
|
||||||
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
||||||
|
|
||||||
for (j=0; j < y; ++j) {
|
// Allocate two scan lines worth of filter workspace buffer.
|
||||||
stbi_uc *cur = a->out + stride*j;
|
filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0);
|
||||||
stbi_uc *prior;
|
if (!filter_buf) return stbi__err("outofmem", "Out of memory");
|
||||||
int filter = *raw++;
|
|
||||||
|
|
||||||
if (filter > 4)
|
|
||||||
return stbi__err("invalid filter","Corrupt PNG");
|
|
||||||
|
|
||||||
|
// Filtering for low-bit-depth images
|
||||||
if (depth < 8) {
|
if (depth < 8) {
|
||||||
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
|
|
||||||
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
|
||||||
filter_bytes = 1;
|
filter_bytes = 1;
|
||||||
width = img_width_bytes;
|
width = img_width_bytes;
|
||||||
}
|
}
|
||||||
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
|
||||||
|
for (j=0; j < y; ++j) {
|
||||||
|
// cur/prior filter buffers alternate
|
||||||
|
stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes;
|
||||||
|
stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes;
|
||||||
|
stbi_uc *dest = a->out + stride*j;
|
||||||
|
int nk = width * filter_bytes;
|
||||||
|
int filter = *raw++;
|
||||||
|
|
||||||
|
// check filter type
|
||||||
|
if (filter > 4) {
|
||||||
|
all_ok = stbi__err("invalid filter","Corrupt PNG");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if first row, use special filter that doesn't sample previous row
|
// if first row, use special filter that doesn't sample previous row
|
||||||
if (j == 0) filter = first_row_filter[filter];
|
if (j == 0) filter = first_row_filter[filter];
|
||||||
|
|
||||||
// handle first byte explicitly
|
// perform actual filtering
|
||||||
for (k=0; k < filter_bytes; ++k) {
|
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
case STBI__F_none : cur[k] = raw[k]; break;
|
case STBI__F_none:
|
||||||
case STBI__F_sub : cur[k] = raw[k]; break;
|
memcpy(cur, raw, nk);
|
||||||
case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
|
break;
|
||||||
case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
|
case STBI__F_sub:
|
||||||
case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
|
memcpy(cur, raw, filter_bytes);
|
||||||
case STBI__F_avg_first : cur[k] = raw[k]; break;
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
case STBI__F_paeth_first: cur[k] = raw[k]; break;
|
cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]);
|
||||||
}
|
break;
|
||||||
|
case STBI__F_up:
|
||||||
|
for (k = 0; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
|
||||||
|
break;
|
||||||
|
case STBI__F_avg:
|
||||||
|
for (k = 0; k < filter_bytes; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1));
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1));
|
||||||
|
break;
|
||||||
|
case STBI__F_paeth:
|
||||||
|
for (k = 0; k < filter_bytes; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes]));
|
||||||
|
break;
|
||||||
|
case STBI__F_avg_first:
|
||||||
|
memcpy(cur, raw, filter_bytes);
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth == 8) {
|
|
||||||
if (img_n != out_n)
|
|
||||||
cur[img_n] = 255; // first pixel
|
|
||||||
raw += img_n;
|
|
||||||
cur += out_n;
|
|
||||||
prior += out_n;
|
|
||||||
} else if (depth == 16) {
|
|
||||||
if (img_n != out_n) {
|
|
||||||
cur[filter_bytes] = 255; // first pixel top byte
|
|
||||||
cur[filter_bytes+1] = 255; // first pixel bottom byte
|
|
||||||
}
|
|
||||||
raw += filter_bytes;
|
|
||||||
cur += output_bytes;
|
|
||||||
prior += output_bytes;
|
|
||||||
} else {
|
|
||||||
raw += 1;
|
|
||||||
cur += 1;
|
|
||||||
prior += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a little gross, so that we don't switch per-pixel or per-component
|
|
||||||
if (depth < 8 || img_n == out_n) {
|
|
||||||
int nk = (width - 1)*filter_bytes;
|
|
||||||
#define STBI__CASE(f) \
|
|
||||||
case f: \
|
|
||||||
for (k=0; k < nk; ++k)
|
|
||||||
switch (filter) {
|
|
||||||
// "none" filter turns into a memcpy here; make that explicit.
|
|
||||||
case STBI__F_none: memcpy(cur, raw, nk); break;
|
|
||||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
|
|
||||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
|
||||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
|
|
||||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
|
|
||||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
|
|
||||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
|
|
||||||
}
|
|
||||||
#undef STBI__CASE
|
|
||||||
raw += nk;
|
raw += nk;
|
||||||
|
|
||||||
|
// expand decoded bits in cur to dest, also adding an extra alpha channel if desired
|
||||||
|
if (depth < 8) {
|
||||||
|
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
||||||
|
stbi_uc *in = cur;
|
||||||
|
stbi_uc *out = dest;
|
||||||
|
stbi_uc inb = 0;
|
||||||
|
stbi__uint32 nsmp = x*img_n;
|
||||||
|
|
||||||
|
// expand bits to bytes first
|
||||||
|
if (depth == 4) {
|
||||||
|
for (i=0; i < nsmp; ++i) {
|
||||||
|
if ((i & 1) == 0) inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 4);
|
||||||
|
inb <<= 4;
|
||||||
|
}
|
||||||
|
} else if (depth == 2) {
|
||||||
|
for (i=0; i < nsmp; ++i) {
|
||||||
|
if ((i & 3) == 0) inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 6);
|
||||||
|
inb <<= 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
STBI_ASSERT(depth == 1);
|
||||||
|
for (i=0; i < nsmp; ++i) {
|
||||||
|
if ((i & 7) == 0) inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 7);
|
||||||
|
inb <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert alpha=255 values if desired
|
||||||
|
if (img_n != out_n)
|
||||||
|
stbi__create_png_alpha_expand8(dest, dest, x, img_n);
|
||||||
|
} else if (depth == 8) {
|
||||||
|
if (img_n == out_n)
|
||||||
|
memcpy(dest, cur, x*img_n);
|
||||||
|
else
|
||||||
|
stbi__create_png_alpha_expand8(dest, cur, x, img_n);
|
||||||
|
} else if (depth == 16) {
|
||||||
|
// convert the image data from big-endian to platform-native
|
||||||
|
stbi__uint16 *dest16 = (stbi__uint16*)dest;
|
||||||
|
stbi__uint32 nsmp = x*img_n;
|
||||||
|
|
||||||
|
if (img_n == out_n) {
|
||||||
|
for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
|
||||||
|
*dest16 = (cur[0] << 8) | cur[1];
|
||||||
} else {
|
} else {
|
||||||
STBI_ASSERT(img_n+1 == out_n);
|
STBI_ASSERT(img_n+1 == out_n);
|
||||||
#define STBI__CASE(f) \
|
|
||||||
case f: \
|
|
||||||
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
|
||||||
for (k=0; k < filter_bytes; ++k)
|
|
||||||
switch (filter) {
|
|
||||||
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
|
|
||||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
|
|
||||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
|
||||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
|
|
||||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
|
|
||||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
|
|
||||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
|
|
||||||
}
|
|
||||||
#undef STBI__CASE
|
|
||||||
|
|
||||||
// the loop above sets the high byte of the pixels' alpha, but for
|
|
||||||
// 16 bit png files we also need the low byte set. we'll do that here.
|
|
||||||
if (depth == 16) {
|
|
||||||
cur = a->out + stride*j; // start at the beginning of the row again
|
|
||||||
for (i=0; i < x; ++i,cur+=output_bytes) {
|
|
||||||
cur[filter_bytes+1] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we make a separate pass to expand bits to pixels; for performance,
|
|
||||||
// this could run two scanlines behind the above code, so it won't
|
|
||||||
// intefere with filtering but will still be in the cache.
|
|
||||||
if (depth < 8) {
|
|
||||||
for (j=0; j < y; ++j) {
|
|
||||||
stbi_uc *cur = a->out + stride*j;
|
|
||||||
stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes;
|
|
||||||
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
|
|
||||||
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
|
|
||||||
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
|
||||||
|
|
||||||
// note that the final byte might overshoot and write more data than desired.
|
|
||||||
// we can allocate enough data that this never writes out of memory, but it
|
|
||||||
// could also overwrite the next scanline. can it overwrite non-empty data
|
|
||||||
// on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
|
|
||||||
// so we need to explicitly clamp the final ones
|
|
||||||
|
|
||||||
if (depth == 4) {
|
|
||||||
for (k=x*img_n; k >= 2; k-=2, ++in) {
|
|
||||||
*cur++ = scale * ((*in >> 4) );
|
|
||||||
*cur++ = scale * ((*in ) & 0x0f);
|
|
||||||
}
|
|
||||||
if (k > 0) *cur++ = scale * ((*in >> 4) );
|
|
||||||
} else if (depth == 2) {
|
|
||||||
for (k=x*img_n; k >= 4; k-=4, ++in) {
|
|
||||||
*cur++ = scale * ((*in >> 6) );
|
|
||||||
*cur++ = scale * ((*in >> 4) & 0x03);
|
|
||||||
*cur++ = scale * ((*in >> 2) & 0x03);
|
|
||||||
*cur++ = scale * ((*in ) & 0x03);
|
|
||||||
}
|
|
||||||
if (k > 0) *cur++ = scale * ((*in >> 6) );
|
|
||||||
if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
|
|
||||||
if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
|
|
||||||
} else if (depth == 1) {
|
|
||||||
for (k=x*img_n; k >= 8; k-=8, ++in) {
|
|
||||||
*cur++ = scale * ((*in >> 7) );
|
|
||||||
*cur++ = scale * ((*in >> 6) & 0x01);
|
|
||||||
*cur++ = scale * ((*in >> 5) & 0x01);
|
|
||||||
*cur++ = scale * ((*in >> 4) & 0x01);
|
|
||||||
*cur++ = scale * ((*in >> 3) & 0x01);
|
|
||||||
*cur++ = scale * ((*in >> 2) & 0x01);
|
|
||||||
*cur++ = scale * ((*in >> 1) & 0x01);
|
|
||||||
*cur++ = scale * ((*in ) & 0x01);
|
|
||||||
}
|
|
||||||
if (k > 0) *cur++ = scale * ((*in >> 7) );
|
|
||||||
if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
|
|
||||||
if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
|
|
||||||
if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
|
|
||||||
if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
|
|
||||||
if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
|
|
||||||
if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
|
|
||||||
}
|
|
||||||
if (img_n != out_n) {
|
|
||||||
int q;
|
|
||||||
// insert alpha = 255
|
|
||||||
cur = a->out + stride*j;
|
|
||||||
if (img_n == 1) {
|
if (img_n == 1) {
|
||||||
for (q=x-1; q >= 0; --q) {
|
for (i = 0; i < x; ++i, dest16 += 2, cur += 2) {
|
||||||
cur[q*2+1] = 255;
|
dest16[0] = (cur[0] << 8) | cur[1];
|
||||||
cur[q*2+0] = cur[q];
|
dest16[1] = 0xffff;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
STBI_ASSERT(img_n == 3);
|
STBI_ASSERT(img_n == 3);
|
||||||
for (q=x-1; q >= 0; --q) {
|
for (i = 0; i < x; ++i, dest16 += 4, cur += 6) {
|
||||||
cur[q*4+3] = 255;
|
dest16[0] = (cur[0] << 8) | cur[1];
|
||||||
cur[q*4+2] = cur[q*3+2];
|
dest16[1] = (cur[2] << 8) | cur[3];
|
||||||
cur[q*4+1] = cur[q*3+1];
|
dest16[2] = (cur[4] << 8) | cur[5];
|
||||||
cur[q*4+0] = cur[q*3+0];
|
dest16[3] = 0xffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (depth == 16) {
|
|
||||||
// force the image data from big-endian to platform-native.
|
|
||||||
// this is done in a separate pass due to the decoding relying
|
|
||||||
// on the data being untouched, but could probably be done
|
|
||||||
// per-line during decode if care is taken.
|
|
||||||
stbi_uc *cur = a->out;
|
|
||||||
stbi__uint16 *cur16 = (stbi__uint16*)cur;
|
|
||||||
|
|
||||||
for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
|
STBI_FREE(filter_buf);
|
||||||
*cur16 = (cur[0] << 8) | cur[1];
|
if (!all_ok) return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -4955,7 +5010,7 @@ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
|
|||||||
static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
|
static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
|
||||||
static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
|
static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
|
||||||
|
|
||||||
STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
|
STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
|
||||||
{
|
{
|
||||||
stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
|
stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
|
||||||
stbi__unpremultiply_on_load_set = 1;
|
stbi__unpremultiply_on_load_set = 1;
|
||||||
@@ -5064,14 +5119,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
if (!pal_img_n) {
|
if (!pal_img_n) {
|
||||||
s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
|
s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
|
||||||
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
|
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
|
||||||
if (scan == STBI__SCAN_header) return 1;
|
|
||||||
} else {
|
} else {
|
||||||
// if paletted, then pal_n is our final components, and
|
// if paletted, then pal_n is our final components, and
|
||||||
// img_n is # components to decompress/filter.
|
// img_n is # components to decompress/filter.
|
||||||
s->img_n = 1;
|
s->img_n = 1;
|
||||||
if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
|
if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
|
||||||
// if SCAN_header, have to scan to see if we have a tRNS
|
|
||||||
}
|
}
|
||||||
|
// even with SCAN_header, have to scan to see if we have a tRNS
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5103,10 +5157,14 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
|
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
|
||||||
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
||||||
has_trans = 1;
|
has_trans = 1;
|
||||||
|
// non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
|
||||||
|
if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
|
||||||
if (z->depth == 16) {
|
if (z->depth == 16) {
|
||||||
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning
|
||||||
|
tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
||||||
} else {
|
} else {
|
||||||
for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
for (k = 0; k < s->img_n && k < 3; ++k)
|
||||||
|
tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -5115,7 +5173,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
case STBI__PNG_TYPE('I','D','A','T'): {
|
case STBI__PNG_TYPE('I','D','A','T'): {
|
||||||
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
|
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
|
||||||
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
|
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
|
||||||
if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
|
if (scan == STBI__SCAN_header) {
|
||||||
|
// header scan definitely stops at first IDAT
|
||||||
|
if (pal_img_n)
|
||||||
|
s->img_n = pal_img_n;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
|
||||||
if ((int)(ioff + c.length) < (int)ioff) return 0;
|
if ((int)(ioff + c.length) < (int)ioff) return 0;
|
||||||
if (ioff + c.length > idata_limit) {
|
if (ioff + c.length > idata_limit) {
|
||||||
stbi__uint32 idata_limit_old = idata_limit;
|
stbi__uint32 idata_limit_old = idata_limit;
|
||||||
@@ -5498,8 +5562,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
psize = (info.offset - info.extra_read - info.hsz) >> 2;
|
psize = (info.offset - info.extra_read - info.hsz) >> 2;
|
||||||
}
|
}
|
||||||
if (psize == 0) {
|
if (psize == 0) {
|
||||||
if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) {
|
// accept some number of extra bytes after the header, but if the offset points either to before
|
||||||
|
// the header ends or implies a large amount of extra data, reject the file as malformed
|
||||||
|
int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original);
|
||||||
|
int header_limit = 1024; // max we actually read is below 256 bytes currently.
|
||||||
|
int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size.
|
||||||
|
if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) {
|
||||||
|
return stbi__errpuc("bad header", "Corrupt BMP");
|
||||||
|
}
|
||||||
|
// we established that bytes_read_so_far is positive and sensible.
|
||||||
|
// the first half of this test rejects offsets that are either too small positives, or
|
||||||
|
// negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn
|
||||||
|
// ensures the number computed in the second half of the test can't overflow.
|
||||||
|
if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) {
|
||||||
return stbi__errpuc("bad offset", "Corrupt BMP");
|
return stbi__errpuc("bad offset", "Corrupt BMP");
|
||||||
|
} else {
|
||||||
|
stbi__skip(s, info.offset - bytes_read_so_far);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7187,12 +7265,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
// Run
|
// Run
|
||||||
value = stbi__get8(s);
|
value = stbi__get8(s);
|
||||||
count -= 128;
|
count -= 128;
|
||||||
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
||||||
for (z = 0; z < count; ++z)
|
for (z = 0; z < count; ++z)
|
||||||
scanline[i++ * 4 + k] = value;
|
scanline[i++ * 4 + k] = value;
|
||||||
} else {
|
} else {
|
||||||
// Dump
|
// Dump
|
||||||
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
||||||
for (z = 0; z < count; ++z)
|
for (z = 0; z < count; ++z)
|
||||||
scanline[i++ * 4 + k] = stbi__get8(s);
|
scanline[i++ * 4 + k] = stbi__get8(s);
|
||||||
}
|
}
|
||||||
@@ -7446,10 +7524,17 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
|
|
||||||
out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
|
out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
|
||||||
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
||||||
stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8));
|
if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
|
||||||
|
STBI_FREE(out);
|
||||||
|
return stbi__errpuc("bad PNM", "PNM file truncated");
|
||||||
|
}
|
||||||
|
|
||||||
if (req_comp && req_comp != s->img_n) {
|
if (req_comp && req_comp != s->img_n) {
|
||||||
|
if (ri->bits_per_channel == 16) {
|
||||||
|
out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
|
||||||
|
} else {
|
||||||
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
|
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
|
||||||
|
}
|
||||||
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
@@ -7486,6 +7571,8 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
|
|||||||
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
|
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
|
||||||
value = value*10 + (*c - '0');
|
value = value*10 + (*c - '0');
|
||||||
*c = (char) stbi__get8(s);
|
*c = (char) stbi__get8(s);
|
||||||
|
if((value > 214748364) || (value == 214748364 && *c > '7'))
|
||||||
|
return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int");
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@@ -7516,9 +7603,13 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
stbi__pnm_skip_whitespace(s, &c);
|
stbi__pnm_skip_whitespace(s, &c);
|
||||||
|
|
||||||
*x = stbi__pnm_getinteger(s, &c); // read width
|
*x = stbi__pnm_getinteger(s, &c); // read width
|
||||||
|
if(*x == 0)
|
||||||
|
return stbi__err("invalid width", "PPM image header had zero or overflowing width");
|
||||||
stbi__pnm_skip_whitespace(s, &c);
|
stbi__pnm_skip_whitespace(s, &c);
|
||||||
|
|
||||||
*y = stbi__pnm_getinteger(s, &c); // read height
|
*y = stbi__pnm_getinteger(s, &c); // read height
|
||||||
|
if (*y == 0)
|
||||||
|
return stbi__err("invalid width", "PPM image header had zero or overflowing width");
|
||||||
stbi__pnm_skip_whitespace(s, &c);
|
stbi__pnm_skip_whitespace(s, &c);
|
||||||
|
|
||||||
maxv = stbi__pnm_getinteger(s, &c); // read max value
|
maxv = stbi__pnm_getinteger(s, &c); // read max value
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ TextFile LoadTextFile(std::string file_path)
|
|||||||
tf.offset[i].x = 0;
|
tf.offset[i].x = 0;
|
||||||
tf.offset[i].y = 0;
|
tf.offset[i].y = 0;
|
||||||
tf.offset[i].w = 0;
|
tf.offset[i].w = 0;
|
||||||
|
tf.box_width = 0;
|
||||||
|
tf.box_height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abre el fichero para leer los valores
|
// Abre el fichero para leer los valores
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <string> // for string, basic_string
|
#include <string> // for string, basic_string
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
#include "input.h" // for inputs_e
|
#include "input.h" // for inputs_e
|
||||||
|
#include "lang.h"
|
||||||
struct JA_Music_t;
|
struct JA_Music_t;
|
||||||
struct JA_Sound_t;
|
struct JA_Sound_t;
|
||||||
enum class ScreenFilter;
|
enum class ScreenFilter;
|
||||||
@@ -113,7 +114,7 @@ struct OptionsAudio
|
|||||||
struct OptionsGame
|
struct OptionsGame
|
||||||
{
|
{
|
||||||
GameDifficulty difficulty; // Dificultad del juego
|
GameDifficulty difficulty; // Dificultad del juego
|
||||||
Uint8 language; // Idioma usado en el juego
|
lang::Code language; // Idioma usado en el juego
|
||||||
bool autofire; // Indica si el jugador ha de pulsar repetidamente para disparar o basta con mantener pulsado
|
bool autofire; // Indica si el jugador ha de pulsar repetidamente para disparar o basta con mantener pulsado
|
||||||
std::vector<HiScoreEntry> hi_score_table; // Tabla con las mejores puntuaciones
|
std::vector<HiScoreEntry> hi_score_table; // Tabla con las mejores puntuaciones
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user