corregides cridades a SDL3 i migrat casi tot de int a float. Falta jail_shader
This commit is contained in:
@@ -140,15 +140,15 @@ void Cheevos::loadFromFile() {
|
||||
// Guarda el estado de los logros en un fichero
|
||||
void Cheevos::saveToFile() {
|
||||
// Abre el fichero en modo escritura (binario)
|
||||
SDL_RWops* file = SDL_RWFromFile(this->file_.c_str(), "w+b");
|
||||
if (file != NULL) {
|
||||
SDL_IOStream* file = SDL_IOFromFile(this->file_.c_str(), "w+b");
|
||||
if (file != nullptr) {
|
||||
// Guarda la información
|
||||
for (int i = 0; i < (int)cheevos_list_.size(); ++i) {
|
||||
SDL_RWwrite(file, &cheevos_list_[i].completed, sizeof(bool), 1);
|
||||
SDL_WriteIO(file, &cheevos_list_[i].completed, sizeof(bool));
|
||||
}
|
||||
|
||||
// Cierra el fichero
|
||||
SDL_RWclose(file);
|
||||
SDL_CloseIO(file);
|
||||
} else {
|
||||
if (options.console) {
|
||||
std::cout << "Error: Unable to save file! " << SDL_GetError() << std::endl;
|
||||
|
||||
@@ -1,61 +1,55 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <algorithm> // Para max
|
||||
#include <memory> // Para __shared_ptr_access, shared_ptr
|
||||
#include "resource.h" // Para Resource
|
||||
#include "text.h" // Para Text
|
||||
#include "utils.h" // Para Color
|
||||
#include <memory> // Para __shared_ptr_access, shared_ptr
|
||||
|
||||
#include "resource.h" // Para Resource
|
||||
#include "text.h" // Para Text
|
||||
#include "utils.h" // Para Color
|
||||
|
||||
// [SINGLETON]
|
||||
Debug *Debug::debug_ = nullptr;
|
||||
Debug* Debug::debug_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
void Debug::init()
|
||||
{
|
||||
Debug::debug_ = new Debug();
|
||||
void Debug::init() {
|
||||
Debug::debug_ = new Debug();
|
||||
}
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
void Debug::destroy()
|
||||
{
|
||||
delete Debug::debug_;
|
||||
void Debug::destroy() {
|
||||
delete Debug::debug_;
|
||||
}
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
||||
Debug *Debug::get()
|
||||
{
|
||||
return Debug::debug_;
|
||||
Debug* Debug::get() {
|
||||
return Debug::debug_;
|
||||
}
|
||||
|
||||
// Dibuja en pantalla
|
||||
void Debug::render()
|
||||
{
|
||||
auto text = Resource::get()->getText("debug");
|
||||
int y = y_;
|
||||
int w = 0;
|
||||
void Debug::render() {
|
||||
auto text = Resource::get()->getText("debug");
|
||||
int y = y_;
|
||||
int w = 0;
|
||||
|
||||
for (const auto &s : slot_)
|
||||
{
|
||||
text->write(x_, y, s);
|
||||
w = (std::max(w, (int)s.length()));
|
||||
y += text->getCharacterSize() + 1;
|
||||
if (y > 192 - text->getCharacterSize())
|
||||
{
|
||||
y = y_;
|
||||
x_ += w * text->getCharacterSize() + 2;
|
||||
}
|
||||
}
|
||||
for (const auto& s : slot_) {
|
||||
text->write(x_, y, s);
|
||||
w = (std::max(w, (int)s.length()));
|
||||
y += text->getCharacterSize() + 1;
|
||||
if (y > 192 - text->getCharacterSize()) {
|
||||
y = y_;
|
||||
x_ += w * text->getCharacterSize() + 2;
|
||||
}
|
||||
}
|
||||
|
||||
y = 0;
|
||||
for (const auto &l : log_)
|
||||
{
|
||||
text->writeColored(x_ + 10, y, l, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
y += text->getCharacterSize() + 1;
|
||||
}
|
||||
y = 0;
|
||||
for (const auto& l : log_) {
|
||||
text->writeColored(x_ + 10, y, l, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
y += text->getCharacterSize() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Establece la posición donde se colocará la información de debug
|
||||
void Debug::setPos(SDL_Point p)
|
||||
{
|
||||
x_ = p.x;
|
||||
y_ = p.y;
|
||||
void Debug::setPos(SDL_FPoint p) {
|
||||
x_ = p.x;
|
||||
y_ = p.y;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class Debug {
|
||||
void render();
|
||||
|
||||
// Establece la posición donde se colocará la información de debug
|
||||
void setPos(SDL_Point p);
|
||||
void setPos(SDL_FPoint p);
|
||||
|
||||
// Getters
|
||||
bool getEnabled() { return enabled_; }
|
||||
|
||||
@@ -11,24 +11,24 @@
|
||||
#include <memory> // Para make_unique, unique_ptr
|
||||
#include <string> // Para operator+, allocator, char_traits
|
||||
|
||||
#include "asset.h" // Para Asset, AssetType
|
||||
#include "cheevos.h" // Para Cheevos
|
||||
#include "credits.h" // Para Credits
|
||||
#include "debug.h" // Para Debug
|
||||
#include "defines.h" // Para WINDOW_CAPTION
|
||||
#include "ending.h" // Para Ending
|
||||
#include "ending2.h" // Para Ending2
|
||||
#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV...
|
||||
#include "game.h" // Para Game, GameMode
|
||||
#include "game_over.h" // Para GameOver
|
||||
#include "input.h" // Para Input, InputAction
|
||||
#include "loading_screen.h" // Para LoadingScreen
|
||||
#include "logo.h" // Para Logo
|
||||
#include "options.h" // Para Options, options, OptionsVideo
|
||||
#include "resource.h" // Para Resource
|
||||
#include "screen.h" // Para Screen
|
||||
#include "title.h" // Para Title
|
||||
#include "ui/notifier.h" // Para Notifier
|
||||
#include "asset.h" // Para Asset, AssetType
|
||||
#include "cheevos.h" // Para Cheevos
|
||||
#include "debug.h" // Para Debug
|
||||
#include "defines.h" // Para WINDOW_CAPTION
|
||||
#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV...
|
||||
#include "input.h" // Para Input, InputAction
|
||||
#include "options.h" // Para Options, options, OptionsVideo
|
||||
#include "resource.h" // Para Resource
|
||||
#include "screen.h" // Para Screen
|
||||
#include "sections/credits.h" // Para Credits
|
||||
#include "sections/ending.h" // Para Ending
|
||||
#include "sections/ending2.h" // Para Ending2
|
||||
#include "sections/game.h" // Para Game, GameMode
|
||||
#include "sections/game_over.h" // Para GameOver
|
||||
#include "sections/loading_screen.h" // Para LoadingScreen
|
||||
#include "sections/logo.h" // Para Logo
|
||||
#include "sections/title.h" // Para Title
|
||||
#include "ui/notifier.h" // Para Notifier
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <pwd.h>
|
||||
@@ -67,7 +67,7 @@ Director::Director(int argc, const char* argv[]) {
|
||||
|
||||
// Crea los objetos
|
||||
Screen::init(window_, renderer_);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_HideCursor();
|
||||
Resource::init();
|
||||
Notifier::init("", "8bithud");
|
||||
Screen::get()->setNotificationsEnabled(true);
|
||||
@@ -220,29 +220,29 @@ void Director::initInput() {
|
||||
const int NUM_GAMEPADS = Input::get()->getNumControllers();
|
||||
for (int i = 0; i < NUM_GAMEPADS; ++i) {
|
||||
// Movimiento
|
||||
Input::get()->bindGameControllerButton(i, InputAction::JUMP, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::JUMP, SDL_GAMEPAD_BUTTON_SOUTH);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::LEFT, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::RIGHT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||
|
||||
// Otros
|
||||
Input::get()->bindGameControllerButton(i, InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::ACCEPT, SDL_GAMEPAD_BUTTON_SOUTH);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::CANCEL, SDL_GAMEPAD_BUTTON_EAST);
|
||||
#ifdef GAME_CONSOLE
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_exit, SDL_CONTROLLER_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_pause, SDL_GAMEPAD_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_exit, SDL_GAMEPAD_BUTTON_START);
|
||||
#else
|
||||
Input::get()->bindGameControllerButton(i, InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::PAUSE, SDL_GAMEPAD_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::EXIT, SDL_GAMEPAD_BUTTON_BACK);
|
||||
#endif
|
||||
Input::get()->bindGameControllerButton(i, InputAction::NEXT_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::NEXT_PALETTE, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_MUSIC, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_BORDER, SDL_GAMEPAD_BUTTON_NORTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa JailAudio
|
||||
void Director::initJailAudio() {
|
||||
JA_Init(48000, AUDIO_S16, 2);
|
||||
JA_Init(48000, SDL_AUDIO_S16LE, 2);
|
||||
if (options.audio.enabled) {
|
||||
JA_SetMusicVolume(options.audio.music.volume);
|
||||
JA_SetSoundVolume(options.audio.sound.volume);
|
||||
@@ -258,7 +258,7 @@ bool Director::initSDL() {
|
||||
bool success = true;
|
||||
|
||||
// Inicializa SDL
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
if (options.console) {
|
||||
std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
@@ -267,23 +267,24 @@ bool Director::initSDL() {
|
||||
// Inicia el generador de numeros aleatorios
|
||||
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
|
||||
|
||||
// Establece el filtro de la textura a nearest
|
||||
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(static_cast<int>(options.video.filter)).c_str())) {
|
||||
if (options.console) {
|
||||
std::cout << "Warning: Nearest texture filtering not enabled!\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Activa el render OpenGL
|
||||
if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")) {
|
||||
std::cout << "Warning: opengl not enabled!\n";
|
||||
}
|
||||
|
||||
// Crea la ventana
|
||||
const auto window_width = options.video.border.enabled ? options.game.width + options.video.border.width * 2 : options.game.width;
|
||||
const auto window_height = options.video.border.enabled ? options.game.height + options.video.border.height * 2 : options.game.height;
|
||||
const auto WINDOW_WIDTH = options.video.border.enabled ? options.game.width + options.video.border.width * 2 : options.game.width;
|
||||
const auto WINDOW_HEIGHT = options.video.border.enabled ? options.game.height + options.video.border.height * 2 : options.game.height;
|
||||
|
||||
window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width * options.window.zoom, window_height * options.window.zoom, SDL_WINDOW_HIDDEN);
|
||||
#ifdef __APPLE__
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_METAL;
|
||||
#else
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL;
|
||||
#endif
|
||||
if (options.video.fullscreen) {
|
||||
window_flags |= SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
window_ = SDL_CreateWindow(WINDOW_CAPTION, WINDOW_WIDTH * options.window.zoom, WINDOW_HEIGHT * options.window.zoom, window_flags);
|
||||
if (window_ == nullptr) {
|
||||
if (options.console) {
|
||||
std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
@@ -291,28 +292,27 @@ bool Director::initSDL() {
|
||||
success = false;
|
||||
} else {
|
||||
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
|
||||
Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
|
||||
if (options.video.vertical_sync) {
|
||||
flags = flags | SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
renderer_ = SDL_CreateRenderer(window_, -1, flags);
|
||||
|
||||
renderer_ = SDL_CreateRenderer(window_, nullptr);
|
||||
if (renderer_ == nullptr) {
|
||||
if (options.console) {
|
||||
std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
success = false;
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"FATAL: Failed to create renderer! SDL Error: %s",
|
||||
SDL_GetError());
|
||||
SDL_DestroyWindow(window_);
|
||||
window_ = nullptr;
|
||||
SDL_Quit();
|
||||
return false;
|
||||
} else {
|
||||
// Inicializa el color de renderizado
|
||||
// Configurar renderer
|
||||
const int EXTRA_WIDTH = options.video.border.enabled ? options.video.border.width * 2 : 0;
|
||||
const int EXTRA_HEIGHT = options.video.border.enabled ? options.video.border.height * 2 : 0;
|
||||
SDL_SetRenderLogicalPresentation(
|
||||
renderer_,
|
||||
options.game.width + EXTRA_WIDTH,
|
||||
options.game.height + EXTRA_HEIGHT,
|
||||
options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
|
||||
// Modifica el tamaño del renderizador
|
||||
const int extra_width = options.video.border.enabled ? options.video.border.width * 2 : 0;
|
||||
const int extra_height = options.video.border.enabled ? options.video.border.height * 2 : 0;
|
||||
SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height);
|
||||
|
||||
// Establece el modo de mezcla
|
||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderVSync(renderer_, options.video.vertical_sync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ Enemy::Enemy(const EnemyData& enemy)
|
||||
sprite_->setWidth(enemy.w);
|
||||
sprite_->setHeight(enemy.h);
|
||||
|
||||
const SDL_RendererFlip FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const SDL_RendererFlip MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_RendererFlip>(FLIP | MIRROR));
|
||||
const SDL_FlipMode FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const SDL_FlipMode MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR));
|
||||
|
||||
collider_ = getRect();
|
||||
|
||||
@@ -87,11 +87,11 @@ void Enemy::checkPath() {
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo que contiene al enemigo
|
||||
SDL_Rect Enemy::getRect() {
|
||||
SDL_FRect Enemy::getRect() {
|
||||
return sprite_->getRect();
|
||||
}
|
||||
|
||||
// Obtiene el rectangulo de colision del enemigo
|
||||
SDL_Rect& Enemy::getCollider() {
|
||||
SDL_FRect& Enemy::getCollider() {
|
||||
return collider_;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class Enemy {
|
||||
int x2_; // Limite derecho de la ruta en el eje X
|
||||
int y1_; // Limite superior de la ruta en el eje Y
|
||||
int y2_; // Limite inferior de la ruta en el eje Y
|
||||
SDL_Rect collider_; // Caja de colisión
|
||||
SDL_FRect collider_; // Caja de colisión
|
||||
bool should_flip_; // Indica si el enemigo hace flip al terminar su ruta
|
||||
bool should_mirror_; // Indica si el enemigo se dibuja volteado verticalmente
|
||||
|
||||
@@ -59,8 +59,8 @@ class Enemy {
|
||||
void update();
|
||||
|
||||
// Devuelve el rectangulo que contiene al enemigo
|
||||
SDL_Rect getRect();
|
||||
SDL_FRect getRect();
|
||||
|
||||
// Obtiene el rectangulo de colision del enemigo
|
||||
SDL_Rect& getCollider();
|
||||
SDL_FRect& getCollider();
|
||||
};
|
||||
|
||||
550
source/external/jail_audio.cpp
vendored
550
source/external/jail_audio.cpp
vendored
@@ -1,211 +1,244 @@
|
||||
#include "external/jail_audio.h"
|
||||
#ifndef JA_USESDLMIXER
|
||||
#include "jail_audio.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdint.h> // Para uint8_t, uint32_t
|
||||
#include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell
|
||||
#include <stdlib.h> // Para free, malloc
|
||||
#include <SDL3/SDL.h> // Para SDL_AudioFormat, SDL_BindAudioStream, SDL_SetAudioStreamGain, SDL_PutAudioStreamData, SDL_DestroyAudioStream, SDL_GetAudioStreamAvailable, Uint8, SDL_CreateAudioStream, SDL_UnbindAudioStream, Uint32, SDL_CloseAudioDevice, SDL_GetTicks, SDL_Log, SDL_free, SDL_AudioSpec, SDL_AudioStream, SDL_IOFromMem, SDL_LoadWAV, SDL_LoadWAV_IO, SDL_OpenAudioDevice, SDL_clamp, SDL_malloc, SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, SDL_AudioDeviceID, SDL_memcpy
|
||||
#include <stdint.h> // Para uint32_t, uint8_t
|
||||
#include <stdio.h> // Para NULL, fseek, printf, fclose, fopen, fread, ftell, FILE, SEEK_END, SEEK_SET
|
||||
#include <stdlib.h> // Para free, malloc
|
||||
#include <string.h> // Para strcpy, strlen
|
||||
|
||||
#include "stb_vorbis.c" // Para stb_vorbis_decode_memory
|
||||
#include "stb_vorbis.h" // Para stb_vorbis_decode_memory
|
||||
|
||||
constexpr int JA_MAX_SIMULTANEOUS_CHANNELS = 20;
|
||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 20
|
||||
#define JA_MAX_GROUPS 2
|
||||
|
||||
struct JA_Sound_t {
|
||||
Uint32 length{0};
|
||||
Uint8* buffer{NULL};
|
||||
struct JA_Sound_t
|
||||
{
|
||||
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
|
||||
Uint32 length { 0 };
|
||||
Uint8 *buffer { NULL };
|
||||
};
|
||||
|
||||
struct JA_Channel_t {
|
||||
JA_Sound_t* sound;
|
||||
int pos{0};
|
||||
int times{0};
|
||||
JA_Channel_state state{JA_CHANNEL_FREE};
|
||||
struct JA_Channel_t
|
||||
{
|
||||
JA_Sound_t *sound { nullptr };
|
||||
int pos { 0 };
|
||||
int times { 0 };
|
||||
int group { 0 };
|
||||
SDL_AudioStream *stream { nullptr };
|
||||
JA_Channel_state state { JA_CHANNEL_FREE };
|
||||
};
|
||||
|
||||
struct JA_Music_t {
|
||||
int samples{0};
|
||||
Uint32 length{0};
|
||||
int pos{0};
|
||||
int times{0};
|
||||
short* output{NULL};
|
||||
JA_Music_state state{JA_MUSIC_INVALID};
|
||||
struct JA_Music_t
|
||||
{
|
||||
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
|
||||
Uint32 length { 0 };
|
||||
Uint8 *buffer { nullptr };
|
||||
char *filename { nullptr };
|
||||
|
||||
int pos { 0 };
|
||||
int times { 0 };
|
||||
SDL_AudioStream *stream { nullptr };
|
||||
JA_Music_state state { JA_MUSIC_INVALID };
|
||||
};
|
||||
|
||||
JA_Music_t* current_music{NULL};
|
||||
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
|
||||
JA_Music_t *current_music { nullptr };
|
||||
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
|
||||
|
||||
int JA_freq{48000};
|
||||
SDL_AudioFormat JA_format{AUDIO_S16};
|
||||
Uint8 JA_channels{2};
|
||||
int JA_musicVolume = 128;
|
||||
int JA_soundVolume = 64;
|
||||
bool JA_musicEnabled = true;
|
||||
bool JA_soundEnabled = true;
|
||||
SDL_AudioDeviceID sdlAudioDevice = 0;
|
||||
SDL_AudioSpec JA_audioSpec { SDL_AUDIO_S16, 2, 48000 };
|
||||
float JA_musicVolume { 1.0f };
|
||||
float JA_soundVolume[JA_MAX_GROUPS];
|
||||
bool JA_musicEnabled { true };
|
||||
bool JA_soundEnabled { true };
|
||||
SDL_AudioDeviceID sdlAudioDevice { 0 };
|
||||
//SDL_TimerID JA_timerID { 0 };
|
||||
|
||||
bool fading = false;
|
||||
int fade_start_time;
|
||||
int fade_duration;
|
||||
int fade_initial_volume;
|
||||
|
||||
void audioCallback(void* userdata, uint8_t* stream, int len) {
|
||||
SDL_memset(stream, 0, len);
|
||||
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
|
||||
int volume = JA_musicVolume;
|
||||
|
||||
void JA_Update()
|
||||
{
|
||||
if (JA_musicEnabled && current_music && current_music->state == JA_MUSIC_PLAYING)
|
||||
{
|
||||
if (fading) {
|
||||
int time = SDL_GetTicks();
|
||||
if (time > (fade_start_time + fade_duration)) {
|
||||
if (time > (fade_start_time+fade_duration)) {
|
||||
fading = false;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
volume = 0;
|
||||
JA_StopMusic();
|
||||
return;
|
||||
} else {
|
||||
const int time_passed = time - fade_start_time;
|
||||
const float percent = (float)time_passed / (float)fade_duration;
|
||||
volume = JA_musicVolume * (1.0 - percent);
|
||||
SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume*(1.0 - percent));
|
||||
}
|
||||
}
|
||||
const int size = SDL_min(len, current_music->length - current_music->pos);
|
||||
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output) + current_music->pos, AUDIO_S16, size, volume);
|
||||
current_music->pos += size;
|
||||
if (size < len) {
|
||||
if (current_music->times != 0) {
|
||||
SDL_MixAudioFormat(stream + size, (Uint8*)current_music->output, AUDIO_S16, len - size, volume);
|
||||
current_music->pos = len - size;
|
||||
if (current_music->times > 0)
|
||||
current_music->times--;
|
||||
} else {
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
|
||||
if (current_music->times != 0)
|
||||
{
|
||||
if ((Uint32)SDL_GetAudioStreamAvailable(current_music->stream) < (current_music->length/2)) {
|
||||
SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length);
|
||||
}
|
||||
if (current_music->times>0) current_music->times--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDL_GetAudioStreamAvailable(current_music->stream) == 0) JA_StopMusic();
|
||||
}
|
||||
}
|
||||
// Mixar els channels mi amol
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) {
|
||||
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
|
||||
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
|
||||
channels[i].pos += size;
|
||||
if (size < len) {
|
||||
if (channels[i].times != 0) {
|
||||
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume);
|
||||
channels[i].pos = len - size;
|
||||
if (channels[i].times > 0)
|
||||
channels[i].times--;
|
||||
} else {
|
||||
JA_StopChannel(i);
|
||||
|
||||
if (JA_soundEnabled)
|
||||
{
|
||||
for (int i=0; i < JA_MAX_SIMULTANEOUS_CHANNELS; ++i)
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
||||
{
|
||||
if (channels[i].times != 0)
|
||||
{
|
||||
if ((Uint32)SDL_GetAudioStreamAvailable(channels[i].stream) < (channels[i].sound->length/2)) {
|
||||
SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer, channels[i].sound->length);
|
||||
if (channels[i].times>0) channels[i].times--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDL_GetAudioStreamAvailable(channels[i].stream) == 0) JA_StopChannel(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
|
||||
JA_freq = freq;
|
||||
JA_format = format;
|
||||
JA_channels = channels;
|
||||
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
|
||||
if (sdlAudioDevice != 0)
|
||||
SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
|
||||
#endif
|
||||
|
||||
SDL_Log("Iniciant JailAudio...");
|
||||
JA_audioSpec = {format, num_channels, freq };
|
||||
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
sdlAudioDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &JA_audioSpec);
|
||||
SDL_Log( (sdlAudioDevice==0) ? "Failed to initialize SDL audio!\n" : "OK!\n");
|
||||
for (int i=0; i<JA_MAX_SIMULTANEOUS_CHANNELS; ++i) channels[i].state = JA_CHANNEL_FREE;
|
||||
for (int i=0; i<JA_MAX_GROUPS; ++i) JA_soundVolume[i] = 0.5f;
|
||||
//SDL_PauseAudioDevice(sdlAudioDevice);
|
||||
//JA_timerID = SDL_AddTimer(30, JA_UpdateCallback, nullptr);
|
||||
}
|
||||
|
||||
void JA_Quit() {
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 1);
|
||||
if (sdlAudioDevice != 0)
|
||||
SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
void JA_Quit()
|
||||
{
|
||||
//if (JA_timerID) SDL_RemoveTimer(JA_timerID);
|
||||
|
||||
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
sdlAudioDevice = 0;
|
||||
}
|
||||
|
||||
JA_Music_t* JA_LoadMusic(Uint8* buffer, Uint32 length) {
|
||||
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
|
||||
{
|
||||
JA_Music_t *music = new JA_Music_t();
|
||||
|
||||
int chan, samplerate;
|
||||
JA_Music_t* music = new JA_Music_t();
|
||||
short *output;
|
||||
music->length = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &output) * chan * 2;
|
||||
|
||||
music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output);
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
|
||||
if (cvt.needed) {
|
||||
cvt.len = music->samples * chan * 2;
|
||||
music->length = cvt.len;
|
||||
cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, music->output, cvt.len);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
free(music->output);
|
||||
music->output = (short*)cvt.buf;
|
||||
}
|
||||
music->length = music->samples * chan * 2;
|
||||
music->spec.channels = chan;
|
||||
music->spec.freq = samplerate;
|
||||
music->spec.format = SDL_AUDIO_S16;
|
||||
music->buffer = (Uint8*)SDL_malloc(music->length);
|
||||
SDL_memcpy(music->buffer, output, music->length);
|
||||
free(output);
|
||||
music->pos = 0;
|
||||
music->state = JA_MUSIC_STOPPED;
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
JA_Music_t* JA_LoadMusic(const char* filename) {
|
||||
JA_Music_t *JA_LoadMusic(const char* filename)
|
||||
{
|
||||
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
|
||||
FILE* f = fopen(filename, "rb");
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Uint8* buffer = (Uint8*)malloc(fsize + 1);
|
||||
if (fread(buffer, fsize, 1, f) != 1)
|
||||
return NULL;
|
||||
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
|
||||
if (fread(buffer, fsize, 1, f)!=1) return NULL;
|
||||
fclose(f);
|
||||
|
||||
JA_Music_t* music = JA_LoadMusic(buffer, fsize);
|
||||
JA_Music_t *music = JA_LoadMusic(buffer, fsize);
|
||||
music->filename = (char*)malloc(strlen(filename)+1);
|
||||
strcpy(music->filename, filename);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
void JA_PlayMusic(JA_Music_t* music, const int loop) {
|
||||
if (!JA_musicEnabled)
|
||||
return;
|
||||
void JA_PlayMusic(JA_Music_t *music, const int loop)
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
|
||||
JA_StopMusic();
|
||||
|
||||
if (current_music != NULL) {
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
}
|
||||
current_music = music;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_PLAYING;
|
||||
current_music->times = loop;
|
||||
|
||||
current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &JA_audioSpec);
|
||||
if (!SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length)) printf("[ERROR] SDL_PutAudioStreamData failed!\n");
|
||||
SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume);
|
||||
if (!SDL_BindAudioStream(sdlAudioDevice, current_music->stream)) printf("[ERROR] SDL_BindAudioStream failed!\n");
|
||||
//SDL_ResumeAudioStreamDevice(current_music->stream);
|
||||
}
|
||||
|
||||
void JA_PauseMusic() {
|
||||
if (!JA_musicEnabled)
|
||||
return;
|
||||
char *JA_GetMusicFilename(JA_Music_t *music)
|
||||
{
|
||||
if (!music) music = current_music;
|
||||
return music->filename;
|
||||
}
|
||||
|
||||
void JA_PauseMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
||||
return;
|
||||
current_music->state = JA_MUSIC_PAUSED;
|
||||
//SDL_PauseAudioStreamDevice(current_music->stream);
|
||||
SDL_UnbindAudioStream(current_music->stream);
|
||||
}
|
||||
|
||||
void JA_ResumeMusic() {
|
||||
if (!JA_musicEnabled)
|
||||
return;
|
||||
void JA_ResumeMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
||||
return;
|
||||
current_music->state = JA_MUSIC_PLAYING;
|
||||
//SDL_ResumeAudioStreamDevice(current_music->stream);
|
||||
SDL_BindAudioStream(sdlAudioDevice, current_music->stream);
|
||||
}
|
||||
|
||||
void JA_StopMusic() {
|
||||
if (!JA_musicEnabled)
|
||||
return;
|
||||
void JA_StopMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
||||
return;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
//SDL_PauseAudioStreamDevice(current_music->stream);
|
||||
SDL_DestroyAudioStream(current_music->stream);
|
||||
current_music->stream = nullptr;
|
||||
free(current_music->filename);
|
||||
current_music->filename = nullptr;
|
||||
}
|
||||
|
||||
void JA_FadeOutMusic(const int milliseconds) {
|
||||
if (!JA_musicEnabled)
|
||||
return;
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
||||
return;
|
||||
void JA_FadeOutMusic(const int milliseconds)
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
|
||||
fading = true;
|
||||
fade_start_time = SDL_GetTicks();
|
||||
@@ -213,204 +246,237 @@ void JA_FadeOutMusic(const int milliseconds) {
|
||||
fade_initial_volume = JA_musicVolume;
|
||||
}
|
||||
|
||||
JA_Music_state JA_GetMusicState() {
|
||||
if (!JA_musicEnabled)
|
||||
return JA_MUSIC_DISABLED;
|
||||
JA_Music_state JA_GetMusicState()
|
||||
{
|
||||
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
|
||||
if (!current_music) return JA_MUSIC_INVALID;
|
||||
|
||||
if (current_music == NULL)
|
||||
return JA_MUSIC_INVALID;
|
||||
return current_music->state;
|
||||
}
|
||||
|
||||
void JA_DeleteMusic(JA_Music_t* music) {
|
||||
if (current_music == music)
|
||||
current_music = NULL;
|
||||
free(music->output);
|
||||
void JA_DeleteMusic(JA_Music_t *music)
|
||||
{
|
||||
if (current_music == music) current_music = nullptr;
|
||||
SDL_free(music->buffer);
|
||||
if (music->stream) SDL_DestroyAudioStream(music->stream);
|
||||
delete music;
|
||||
}
|
||||
|
||||
int JA_SetMusicVolume(int volume) {
|
||||
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
|
||||
: volume;
|
||||
float JA_SetMusicVolume(float volume)
|
||||
{
|
||||
JA_musicVolume = SDL_clamp( volume, 0.0f, 1.0f );
|
||||
if (current_music) SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume);
|
||||
return JA_musicVolume;
|
||||
}
|
||||
|
||||
void JA_SetMusicPosition(float value) {
|
||||
if (!current_music)
|
||||
return;
|
||||
current_music->pos = value * JA_freq;
|
||||
void JA_SetMusicPosition(float value)
|
||||
{
|
||||
if (!current_music) return;
|
||||
current_music->pos = value * current_music->spec.freq;
|
||||
}
|
||||
|
||||
float JA_GetMusicPosition() {
|
||||
if (!current_music)
|
||||
return 0;
|
||||
return float(current_music->pos) / float(JA_freq);
|
||||
float JA_GetMusicPosition()
|
||||
{
|
||||
if (!current_music) return 0;
|
||||
return float(current_music->pos)/float(current_music->spec.freq);
|
||||
}
|
||||
|
||||
void JA_EnableMusic(const bool value) {
|
||||
if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING)
|
||||
JA_StopMusic();
|
||||
void JA_EnableMusic(const bool value)
|
||||
{
|
||||
if ( !value && current_music && (current_music->state==JA_MUSIC_PLAYING) ) JA_StopMusic();
|
||||
|
||||
JA_musicEnabled = value;
|
||||
}
|
||||
|
||||
JA_Sound_t* JA_NewSound(Uint8* buffer, Uint32 length) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
|
||||
|
||||
|
||||
|
||||
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length)
|
||||
{
|
||||
JA_Sound_t *sound = new JA_Sound_t();
|
||||
sound->buffer = buffer;
|
||||
sound->length = length;
|
||||
return sound;
|
||||
}
|
||||
|
||||
JA_Sound_t* JA_LoadSound(uint8_t* buffer, uint32_t size) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
SDL_AudioSpec wavSpec;
|
||||
SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size), 1, &wavSpec, &sound->buffer, &sound->length);
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
||||
cvt.len = sound->length;
|
||||
cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
SDL_FreeWAV(sound->buffer);
|
||||
sound->buffer = cvt.buf;
|
||||
sound->length = cvt.len_cvt;
|
||||
JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size)
|
||||
{
|
||||
JA_Sound_t *sound = new JA_Sound_t();
|
||||
SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &sound->spec, &sound->buffer, &sound->length);
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
JA_Sound_t* JA_LoadSound(const char* filename) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
SDL_AudioSpec wavSpec;
|
||||
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
||||
cvt.len = sound->length;
|
||||
cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
SDL_FreeWAV(sound->buffer);
|
||||
sound->buffer = cvt.buf;
|
||||
sound->length = cvt.len_cvt;
|
||||
JA_Sound_t *JA_LoadSound(const char* filename)
|
||||
{
|
||||
JA_Sound_t *sound = new JA_Sound_t();
|
||||
SDL_LoadWAV(filename, &sound->spec, &sound->buffer, &sound->length);
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
int JA_PlaySound(JA_Sound_t* sound, const int loop) {
|
||||
if (!JA_soundEnabled)
|
||||
return -1;
|
||||
int JA_PlaySound(JA_Sound_t *sound, const int loop, const int group)
|
||||
{
|
||||
if (!JA_soundEnabled) return -1;
|
||||
|
||||
int channel = 0;
|
||||
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) {
|
||||
channel++;
|
||||
}
|
||||
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
channel = 0;
|
||||
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
|
||||
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
|
||||
JA_StopChannel(channel);
|
||||
|
||||
channels[channel].sound = sound;
|
||||
channels[channel].times = loop;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec);
|
||||
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
|
||||
SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]);
|
||||
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int loop) {
|
||||
if (!JA_soundEnabled)
|
||||
return -1;
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop, const int group)
|
||||
{
|
||||
if (!JA_soundEnabled) return -1;
|
||||
|
||||
if (channel >= JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
return -1;
|
||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return -1;
|
||||
JA_StopChannel(channel);
|
||||
|
||||
channels[channel].sound = sound;
|
||||
channels[channel].times = loop;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec);
|
||||
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
|
||||
SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]);
|
||||
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
void JA_DeleteSound(JA_Sound_t* sound) {
|
||||
void JA_DeleteSound(JA_Sound_t *sound)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].sound == sound)
|
||||
JA_StopChannel(i);
|
||||
if (channels[i].sound == sound) JA_StopChannel(i);
|
||||
}
|
||||
SDL_free(sound->buffer);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
void JA_PauseChannel(const int channel) {
|
||||
if (!JA_soundEnabled)
|
||||
return;
|
||||
void JA_PauseChannel(const int channel)
|
||||
{
|
||||
if (!JA_soundEnabled) return;
|
||||
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channel == -1)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
||||
{
|
||||
channels[i].state = JA_CHANNEL_PAUSED;
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
//SDL_PauseAudioStreamDevice(channels[i].stream);
|
||||
SDL_UnbindAudioStream(channels[i].stream);
|
||||
}
|
||||
}
|
||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
{
|
||||
if (channels[channel].state == JA_CHANNEL_PLAYING)
|
||||
{
|
||||
channels[channel].state = JA_CHANNEL_PAUSED;
|
||||
}
|
||||
}
|
||||
|
||||
void JA_ResumeChannel(const int channel) {
|
||||
if (!JA_soundEnabled)
|
||||
return;
|
||||
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PAUSED)
|
||||
channels[i].state = JA_CHANNEL_PLAYING;
|
||||
//SDL_PauseAudioStreamDevice(channels[channel].stream);
|
||||
SDL_UnbindAudioStream(channels[channel].stream);
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
if (channels[channel].state == JA_CHANNEL_PAUSED)
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
}
|
||||
}
|
||||
|
||||
void JA_StopChannel(const int channel) {
|
||||
if (!JA_soundEnabled)
|
||||
return;
|
||||
void JA_ResumeChannel(const int channel)
|
||||
{
|
||||
if (!JA_soundEnabled) return;
|
||||
|
||||
if (channel == -1) {
|
||||
if (channel == -1)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
||||
if (channels[i].state == JA_CHANNEL_PAUSED)
|
||||
{
|
||||
channels[i].state = JA_CHANNEL_PLAYING;
|
||||
//SDL_ResumeAudioStreamDevice(channels[i].stream);
|
||||
SDL_BindAudioStream(sdlAudioDevice, channels[i].stream);
|
||||
}
|
||||
}
|
||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
{
|
||||
if (channels[channel].state == JA_CHANNEL_PAUSED)
|
||||
{
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
//SDL_ResumeAudioStreamDevice(channels[channel].stream);
|
||||
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JA_StopChannel(const int channel)
|
||||
{
|
||||
if (!JA_soundEnabled) return;
|
||||
|
||||
if (channel == -1)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[i].stream);
|
||||
channels[i].stream = nullptr;
|
||||
channels[i].state = JA_CHANNEL_FREE;
|
||||
channels[i].pos = 0;
|
||||
channels[i].sound = NULL;
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
}
|
||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
{
|
||||
if (channels[channel].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[channel].stream);
|
||||
channels[channel].stream = nullptr;
|
||||
channels[channel].state = JA_CHANNEL_FREE;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].sound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JA_Channel_state JA_GetChannelState(const int channel) {
|
||||
if (!JA_soundEnabled)
|
||||
return JA_SOUND_DISABLED;
|
||||
JA_Channel_state JA_GetChannelState(const int channel)
|
||||
{
|
||||
if (!JA_soundEnabled) return JA_SOUND_DISABLED;
|
||||
|
||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
|
||||
|
||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS)
|
||||
return JA_CHANNEL_INVALID;
|
||||
return channels[channel].state;
|
||||
}
|
||||
|
||||
int JA_SetSoundVolume(int volume) {
|
||||
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0
|
||||
: volume;
|
||||
return JA_soundVolume;
|
||||
float JA_SetSoundVolume(float volume, const int group)
|
||||
{
|
||||
const float v = SDL_clamp( volume, 0.0f, 1.0f );
|
||||
for (int i = 0; i < JA_MAX_GROUPS; ++i) {
|
||||
if (group==-1 || group==i) JA_soundVolume[i]=v;
|
||||
}
|
||||
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
||||
if ( ((channels[i].state == JA_CHANNEL_PLAYING) || (channels[i].state == JA_CHANNEL_PAUSED)) &&
|
||||
((group==-1) || (channels[i].group==group)) )
|
||||
SDL_SetAudioStreamGain(channels[i].stream, JA_soundVolume[i]);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void JA_EnableSound(const bool value) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
||||
JA_StopChannel(i);
|
||||
void JA_EnableSound(const bool value)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
||||
{
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i);
|
||||
}
|
||||
JA_soundEnabled = value;
|
||||
}
|
||||
|
||||
int JA_SetVolume(int volume) {
|
||||
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
|
||||
: volume;
|
||||
JA_soundVolume = JA_musicVolume / 2;
|
||||
float JA_SetVolume(float volume)
|
||||
{
|
||||
JA_SetSoundVolume(JA_SetMusicVolume(volume) / 2.0f);
|
||||
|
||||
return JA_musicVolume;
|
||||
}
|
||||
|
||||
#endif
|
||||
49
source/external/jail_audio.h
vendored
49
source/external/jail_audio.h
vendored
@@ -1,55 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
struct JA_Music_t; // lines 5-5
|
||||
struct JA_Sound_t; // lines 6-6
|
||||
|
||||
enum JA_Channel_state {
|
||||
JA_CHANNEL_INVALID,
|
||||
JA_CHANNEL_FREE,
|
||||
JA_CHANNEL_PLAYING,
|
||||
JA_CHANNEL_PAUSED,
|
||||
JA_SOUND_DISABLED
|
||||
};
|
||||
enum JA_Music_state {
|
||||
JA_MUSIC_INVALID,
|
||||
JA_MUSIC_PLAYING,
|
||||
JA_MUSIC_PAUSED,
|
||||
JA_MUSIC_STOPPED,
|
||||
JA_MUSIC_DISABLED
|
||||
};
|
||||
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED };
|
||||
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED };
|
||||
|
||||
struct JA_Sound_t;
|
||||
struct JA_Music_t;
|
||||
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
|
||||
void JA_Update();
|
||||
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels);
|
||||
void JA_Quit();
|
||||
|
||||
JA_Music_t* JA_LoadMusic(const char* filename);
|
||||
JA_Music_t* JA_LoadMusic(Uint8* buffer, Uint32 length);
|
||||
void JA_PlayMusic(JA_Music_t* music, const int loop = -1);
|
||||
JA_Music_t *JA_LoadMusic(const char* filename);
|
||||
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length);
|
||||
void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
|
||||
char *JA_GetMusicFilename(JA_Music_t *music = nullptr);
|
||||
void JA_PauseMusic();
|
||||
void JA_ResumeMusic();
|
||||
void JA_StopMusic();
|
||||
void JA_FadeOutMusic(const int milliseconds);
|
||||
JA_Music_state JA_GetMusicState();
|
||||
void JA_DeleteMusic(JA_Music_t* music);
|
||||
int JA_SetMusicVolume(int volume);
|
||||
void JA_DeleteMusic(JA_Music_t *music);
|
||||
float JA_SetMusicVolume(float volume);
|
||||
void JA_SetMusicPosition(float value);
|
||||
float JA_GetMusicPosition();
|
||||
void JA_EnableMusic(const bool value);
|
||||
|
||||
JA_Sound_t* JA_NewSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t* JA_LoadSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t* JA_LoadSound(const char* filename);
|
||||
int JA_PlaySound(JA_Sound_t* sound, const int loop = 0);
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int loop = 0);
|
||||
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t *JA_LoadSound(const char* filename);
|
||||
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0, const int group=0);
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop = 0, const int group=0);
|
||||
void JA_PauseChannel(const int channel);
|
||||
void JA_ResumeChannel(const int channel);
|
||||
void JA_StopChannel(const int channel);
|
||||
JA_Channel_state JA_GetChannelState(const int channel);
|
||||
void JA_DeleteSound(JA_Sound_t* sound);
|
||||
int JA_SetSoundVolume(int volume);
|
||||
void JA_DeleteSound(JA_Sound_t *sound);
|
||||
float JA_SetSoundVolume(float volume, const int group=0);
|
||||
void JA_EnableSound(const bool value);
|
||||
|
||||
int JA_SetVolume(int volume);
|
||||
float JA_SetVolume(float volume);
|
||||
|
||||
4
source/external/jail_shader.cpp
vendored
4
source/external/jail_shader.cpp
vendored
@@ -25,8 +25,8 @@ SDL_Window* win = nullptr;
|
||||
SDL_Renderer* renderer = nullptr;
|
||||
GLuint programId = 0;
|
||||
SDL_Texture* backBuffer = nullptr;
|
||||
SDL_Point win_size = {320 * 4, 256 * 4};
|
||||
SDL_Point tex_size = {320, 256};
|
||||
SDL_FPoint win_size = {320 * 4, 256 * 4};
|
||||
SDL_FPoint tex_size = {320, 256};
|
||||
bool usingOpenGL = false;
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
@@ -8,13 +8,13 @@ namespace globalEvents
|
||||
void check(const SDL_Event &event)
|
||||
{
|
||||
// Evento de salida de la aplicación
|
||||
if (event.type == SDL_QUIT)
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
{
|
||||
options.section.section = Section::QUIT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type == SDL_RENDER_DEVICE_RESET || event.type == SDL_RENDER_TARGETS_RESET)
|
||||
if (event.type == SDL_EVENT_RENDER_DEVICE_RESET || event.type == SDL_EVENT_RENDER_TARGETS_RESET)
|
||||
{
|
||||
// reLoadTextures();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ void check() {
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, INPUT_DO_NOT_ALLOW_REPEAT)) {
|
||||
Screen::get()->toggleVideoMode();
|
||||
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
|
||||
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.fullscreen == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, INPUT_DO_NOT_ALLOW_REPEAT)) {
|
||||
@@ -91,9 +91,8 @@ void check() {
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_INTEGER_SCALE, INPUT_DO_NOT_ALLOW_REPEAT)) {
|
||||
options.video.integer_scale = !options.video.integer_scale;
|
||||
SDL_RenderSetIntegerScale(Screen::get()->getRenderer(), options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
|
||||
Screen::get()->setVideoMode(options.video.mode);
|
||||
Screen::get()->toggleIntegerScale();
|
||||
Screen::get()->setVideoMode(options.video.fullscreen);
|
||||
Notifier::get()->show({"INTEGER SCALE " + std::string(options.video.integer_scale ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ void Input::bindKey(InputAction input, SDL_Scancode code) {
|
||||
}
|
||||
|
||||
// Asigna inputs a botones del mando
|
||||
void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button) {
|
||||
void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button) {
|
||||
if (controller_index < num_gamepads_) {
|
||||
controller_bindings_.at(controller_index).at(static_cast<int>(input)).button = button;
|
||||
}
|
||||
@@ -66,20 +66,20 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device,
|
||||
const int input_index = static_cast<int>(input);
|
||||
|
||||
if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY) {
|
||||
const Uint8* keyStates = SDL_GetKeyboardState(nullptr);
|
||||
auto key_states = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
if (repeat) {
|
||||
success_keyboard = keyStates[key_bindings_[input_index].scancode] != 0;
|
||||
success_keyboard = key_states[key_bindings_[input_index].scancode] != 0;
|
||||
} else {
|
||||
if (!key_bindings_[input_index].active) {
|
||||
if (keyStates[key_bindings_[input_index].scancode] != 0) {
|
||||
if (key_states[key_bindings_[input_index].scancode] != 0) {
|
||||
key_bindings_[input_index].active = true;
|
||||
success_keyboard = true;
|
||||
} else {
|
||||
success_keyboard = false;
|
||||
}
|
||||
} else {
|
||||
if (keyStates[key_bindings_[input_index].scancode] == 0) {
|
||||
if (key_states[key_bindings_[input_index].scancode] == 0) {
|
||||
key_bindings_[input_index].active = false;
|
||||
}
|
||||
success_keyboard = false;
|
||||
@@ -93,17 +93,17 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device,
|
||||
|
||||
if (!success_controller) {
|
||||
if (repeat) {
|
||||
success_controller = SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0;
|
||||
success_controller = SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0;
|
||||
} else {
|
||||
if (!controller_bindings_.at(controller_index).at(input_index).active) {
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0) {
|
||||
if (SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0) {
|
||||
controller_bindings_.at(controller_index).at(input_index).active = true;
|
||||
success_controller = true;
|
||||
} else {
|
||||
success_controller = false;
|
||||
}
|
||||
} else {
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) == 0) {
|
||||
if (SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) == 0) {
|
||||
controller_bindings_.at(controller_index).at(input_index).active = false;
|
||||
}
|
||||
success_controller = false;
|
||||
@@ -119,10 +119,10 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device,
|
||||
// Comprueba si hay almenos un input activo
|
||||
bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) {
|
||||
if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY) {
|
||||
const Uint8* mKeystates = SDL_GetKeyboardState(nullptr);
|
||||
const bool *key_states = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
for (int i = 0; i < (int)key_bindings_.size(); ++i) {
|
||||
if (mKeystates[key_bindings_[i].scancode] != 0 && !key_bindings_[i].active) {
|
||||
if (key_states[key_bindings_[i].scancode] != 0 && !key_bindings_[i].active) {
|
||||
key_bindings_[i].active = true;
|
||||
return true;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) {
|
||||
if (gameControllerFound()) {
|
||||
if (device == InputDeviceToUse::CONTROLLER || device == InputDeviceToUse::ANY) {
|
||||
for (int i = 0; i < (int)controller_bindings_.size(); ++i) {
|
||||
if (SDL_GameControllerGetButton(connected_controllers_[controller_index], controller_bindings_[controller_index][i].button) != 0 && !controller_bindings_[controller_index][i].active) {
|
||||
if (SDL_GetGamepadButton(connected_controllers_[controller_index], controller_bindings_[controller_index][i].button) != 0 && !controller_bindings_[controller_index][i].active) {
|
||||
controller_bindings_[controller_index][i].active = true;
|
||||
return true;
|
||||
}
|
||||
@@ -147,23 +147,32 @@ bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) {
|
||||
bool Input::discoverGameControllers() {
|
||||
bool found = false;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1) {
|
||||
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
// Asegúrate de que el subsistema de gamepads está inicializado
|
||||
if (SDL_WasInit(SDL_INIT_GAMEPAD) != 1) {
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
}
|
||||
|
||||
if (SDL_GameControllerAddMappingsFromFile(game_controller_db_path_.c_str()) < 0) {
|
||||
std::cout << "Error, could not load " << game_controller_db_path_.c_str() << " file: " << SDL_GetError() << std::endl;
|
||||
// Carga el mapping de mandos desde archivo
|
||||
if (SDL_AddGamepadMappingsFromFile(game_controller_db_path_.c_str()) < 0) {
|
||||
std::cout << "Error, could not load " << game_controller_db_path_.c_str()
|
||||
<< " file: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
|
||||
num_joysticks_ = SDL_NumJoysticks();
|
||||
// En SDL3 ya no existe SDL_NumJoysticks()
|
||||
// Ahora se obtiene un array dinámico de IDs
|
||||
int num_joysticks = 0;
|
||||
SDL_JoystickID* joystick_ids = SDL_GetJoysticks(&num_joysticks);
|
||||
|
||||
num_joysticks_ = num_joysticks;
|
||||
num_gamepads_ = 0;
|
||||
|
||||
// Cuenta el número de mandos
|
||||
joysticks_.clear();
|
||||
|
||||
// Recorremos todos los joysticks detectados
|
||||
for (int i = 0; i < num_joysticks_; ++i) {
|
||||
auto joy = SDL_JoystickOpen(i);
|
||||
SDL_Joystick* joy = SDL_OpenJoystick(joystick_ids[i]);
|
||||
joysticks_.push_back(joy);
|
||||
if (SDL_IsGameController(i)) {
|
||||
|
||||
if (SDL_IsGamepad(joystick_ids[i])) {
|
||||
num_gamepads_++;
|
||||
}
|
||||
}
|
||||
@@ -179,26 +188,32 @@ bool Input::discoverGameControllers() {
|
||||
if (num_gamepads_ > 0) {
|
||||
found = true;
|
||||
|
||||
for (int i = 0; i < num_gamepads_; i++) {
|
||||
// Abre el mando y lo añade a la lista
|
||||
auto pad = SDL_GameControllerOpen(i);
|
||||
if (SDL_GameControllerGetAttached(pad) == 1) {
|
||||
connected_controllers_.push_back(pad);
|
||||
const std::string name = SDL_GameControllerNameForIndex(i);
|
||||
std::cout << "#" << i << ": " << name << std::endl;
|
||||
controller_names_.push_back(name);
|
||||
} else {
|
||||
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
|
||||
for (int i = 0; i < num_joysticks_; i++) {
|
||||
if (SDL_IsGamepad(joystick_ids[i])) {
|
||||
SDL_Gamepad* pad = SDL_OpenGamepad(joystick_ids[i]);
|
||||
if (pad && SDL_GamepadConnected(pad)) {
|
||||
connected_controllers_.push_back(pad);
|
||||
|
||||
const char* name = SDL_GetGamepadName(pad);
|
||||
std::cout << "#" << i << ": " << (name ? name : "Unknown") << std::endl;
|
||||
controller_names_.push_back(name ? name : "Unknown");
|
||||
} else {
|
||||
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GameControllerEventState(SDL_ENABLE);
|
||||
// En SDL3 ya no hace falta SDL_GameControllerEventState()
|
||||
// Los eventos de gamepad están siempre habilitados
|
||||
}
|
||||
|
||||
SDL_free(joystick_ids);
|
||||
|
||||
std::cout << "\n** FINISHED LOOKING FOR GAME CONTROLLERS" << std::endl;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
// Comprueba si hay algun mando conectado
|
||||
bool Input::gameControllerFound() { return num_gamepads_ > 0 ? true : false; }
|
||||
|
||||
@@ -211,15 +226,15 @@ int Input::getNumControllers() const { return num_gamepads_; }
|
||||
// Obtiene el indice del controlador a partir de un event.id
|
||||
int Input::getJoyIndex(int id) const {
|
||||
for (int i = 0; i < num_joysticks_; ++i) {
|
||||
if (SDL_JoystickInstanceID(joysticks_[i]) == id) {
|
||||
if (SDL_GetJoystickID(joysticks_[i]) == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Obtiene el SDL_GameControllerButton asignado a un input
|
||||
SDL_GameControllerButton Input::getControllerBinding(int controller_index, InputAction input) const {
|
||||
// Obtiene el SDL_GamepadButton asignado a un input
|
||||
SDL_GamepadButton Input::getControllerBinding(int controller_index, InputAction input) const {
|
||||
return controller_bindings_[controller_index][static_cast<int>(input)].button;
|
||||
}
|
||||
|
||||
@@ -237,16 +252,16 @@ bool Input::checkAxisInput(InputAction input, int controller_index, bool repeat)
|
||||
|
||||
switch (input) {
|
||||
case InputAction::LEFT:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) < -threshold;
|
||||
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) < -threshold;
|
||||
break;
|
||||
case InputAction::RIGHT:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) > threshold;
|
||||
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) > threshold;
|
||||
break;
|
||||
case InputAction::UP:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) < -threshold;
|
||||
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) < -threshold;
|
||||
break;
|
||||
case InputAction::DOWN:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) > threshold;
|
||||
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) > threshold;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -61,19 +61,19 @@ class Input {
|
||||
};
|
||||
|
||||
struct ControllerBindings {
|
||||
SDL_GameControllerButton button; // GameControllerButton asociado
|
||||
SDL_GamepadButton button; // GameControllerButton asociado
|
||||
bool active; // Indica si está activo
|
||||
bool axis_active; // Estado del eje
|
||||
|
||||
// Constructor
|
||||
explicit ControllerBindings(SDL_GameControllerButton btn = SDL_CONTROLLER_BUTTON_INVALID, bool act = false, bool axis_act = false)
|
||||
explicit ControllerBindings(SDL_GamepadButton btn = SDL_GAMEPAD_BUTTON_INVALID, bool act = false, bool axis_act = false)
|
||||
: button(btn),
|
||||
active(act),
|
||||
axis_active(axis_act) {}
|
||||
};
|
||||
|
||||
// Variables
|
||||
std::vector<SDL_GameController*> connected_controllers_; // Vector con todos los mandos conectados
|
||||
std::vector<SDL_Gamepad*> connected_controllers_; // Vector con todos los mandos conectados
|
||||
std::vector<SDL_Joystick*> joysticks_; // Vector con todos los joysticks conectados
|
||||
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
||||
std::vector<std::vector<ControllerBindings>> controller_bindings_; // Vector con los botones asociadas a los inputs predefinidos para cada mando
|
||||
@@ -106,7 +106,7 @@ class Input {
|
||||
void bindKey(InputAction input, SDL_Scancode code);
|
||||
|
||||
// Asigna inputs a botones del mando
|
||||
void bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button);
|
||||
void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button);
|
||||
void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource);
|
||||
|
||||
// Comprueba si un input esta activo
|
||||
@@ -130,8 +130,8 @@ class Input {
|
||||
// Obtiene el indice del controlador a partir de un event.id
|
||||
int getJoyIndex(int id) const;
|
||||
|
||||
// Obtiene el SDL_GameControllerButton asignado a un input
|
||||
SDL_GameControllerButton getControllerBinding(int controller_index, InputAction input) const;
|
||||
// Obtiene el SDL_GamepadButton asignado a un input
|
||||
SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const;
|
||||
|
||||
// Obtiene el indice a partir del nombre del mando
|
||||
int getIndexByName(const std::string& name) const;
|
||||
|
||||
@@ -27,8 +27,8 @@ void Item::render() {
|
||||
}
|
||||
|
||||
// Obtiene su ubicación
|
||||
SDL_Point Item::getPos() {
|
||||
const SDL_Point p = {sprite_->getX(), sprite_->getY()};
|
||||
SDL_FPoint Item::getPos() {
|
||||
const SDL_FPoint p = {sprite_->getX(), sprite_->getY()};
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class Item {
|
||||
// Variables
|
||||
std::vector<Uint8> color_; // Vector con los colores del objeto
|
||||
int counter_; // Contador interno
|
||||
SDL_Rect collider_; // Rectangulo de colisión
|
||||
SDL_FRect collider_; // Rectangulo de colisión
|
||||
int change_color_speed; // Cuanto mas alto, mas tarda en cambiar de color
|
||||
|
||||
public:
|
||||
@@ -54,10 +54,10 @@ class Item {
|
||||
void update() { counter_++; }
|
||||
|
||||
// Obtiene el rectangulo de colision del objeto
|
||||
SDL_Rect& getCollider() { return collider_; }
|
||||
SDL_FRect& getCollider() { return collider_; }
|
||||
|
||||
// Obtiene su ubicación
|
||||
SDL_Point getPos();
|
||||
SDL_FPoint getPos();
|
||||
|
||||
// Asigna los colores del objeto
|
||||
void setColors(Uint8 col1, Uint8 col2);
|
||||
|
||||
@@ -1,35 +1,29 @@
|
||||
#include "item_tracker.h"
|
||||
|
||||
// [SINGLETON]
|
||||
ItemTracker *ItemTracker::item_tracker_ = nullptr;
|
||||
ItemTracker* ItemTracker::item_tracker_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
void ItemTracker::init()
|
||||
{
|
||||
void ItemTracker::init() {
|
||||
ItemTracker::item_tracker_ = new ItemTracker();
|
||||
}
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
void ItemTracker::destroy()
|
||||
{
|
||||
void ItemTracker::destroy() {
|
||||
delete ItemTracker::item_tracker_;
|
||||
}
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
||||
ItemTracker *ItemTracker::get()
|
||||
{
|
||||
ItemTracker* ItemTracker::get() {
|
||||
return ItemTracker::item_tracker_;
|
||||
}
|
||||
|
||||
// Comprueba si el objeto ya ha sido cogido
|
||||
bool ItemTracker::hasBeenPicked(const std::string &name, SDL_Point pos)
|
||||
{
|
||||
bool ItemTracker::hasBeenPicked(const std::string& name, SDL_FPoint pos) {
|
||||
// Primero busca si ya hay una entrada con ese nombre
|
||||
if (const int index = findByName(name); index != -1)
|
||||
{
|
||||
if (const int index = findByName(name); index != -1) {
|
||||
// Luego busca si existe ya una entrada con esa posición
|
||||
if (findByPos(index, pos) != -1)
|
||||
{
|
||||
if (findByPos(index, pos) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -38,33 +32,26 @@ bool ItemTracker::hasBeenPicked(const std::string &name, SDL_Point pos)
|
||||
}
|
||||
|
||||
// Añade el objeto a la lista de objetos cogidos
|
||||
void ItemTracker::addItem(const std::string &name, SDL_Point pos)
|
||||
{
|
||||
void ItemTracker::addItem(const std::string& name, SDL_FPoint pos) {
|
||||
// Comprueba si el objeto no ha sido recogido con anterioridad
|
||||
if (!hasBeenPicked(name, pos))
|
||||
{
|
||||
if (!hasBeenPicked(name, pos)) {
|
||||
// Primero busca si ya hay una entrada con ese nombre
|
||||
if (const int index = findByName(name); index != -1)
|
||||
{
|
||||
if (const int index = findByName(name); index != -1) {
|
||||
item_list_.at(index).pos.push_back(pos);
|
||||
}
|
||||
// En caso contrario crea la entrada
|
||||
else
|
||||
{
|
||||
else {
|
||||
item_list_.emplace_back(name, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Busca una entrada en la lista por nombre
|
||||
int ItemTracker::findByName(const std::string &name)
|
||||
{
|
||||
int ItemTracker::findByName(const std::string& name) {
|
||||
int i = 0;
|
||||
|
||||
for (const auto &l : item_list_)
|
||||
{
|
||||
if (l.name == name)
|
||||
{
|
||||
for (const auto& l : item_list_) {
|
||||
if (l.name == name) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
@@ -74,14 +61,11 @@ int ItemTracker::findByName(const std::string &name)
|
||||
}
|
||||
|
||||
// Busca una entrada en la lista por posición
|
||||
int ItemTracker::findByPos(int index, SDL_Point pos)
|
||||
{
|
||||
int ItemTracker::findByPos(int index, SDL_FPoint pos) {
|
||||
int i = 0;
|
||||
|
||||
for (const auto &l : item_list_[index].pos)
|
||||
{
|
||||
if ((l.x == pos.x) && (l.y == pos.y))
|
||||
{
|
||||
for (const auto& l : item_list_[index].pos) {
|
||||
if ((l.x == pos.x) && (l.y == pos.y)) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include <vector> // Para vector
|
||||
|
||||
struct ItemTrackerData {
|
||||
std::string name; // Nombre de la habitación donde se encuentra el objeto
|
||||
std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación
|
||||
std::string name; // Nombre de la habitación donde se encuentra el objeto
|
||||
std::vector<SDL_FPoint> pos; // Lista de objetos cogidos de la habitación
|
||||
|
||||
// Constructor
|
||||
ItemTrackerData(const std::string& name, const SDL_Point& position)
|
||||
ItemTrackerData(const std::string& name, const SDL_FPoint& position)
|
||||
: name(name) {
|
||||
pos.push_back(position);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class ItemTracker {
|
||||
int findByName(const std::string& name);
|
||||
|
||||
// Busca una entrada en la lista por posición
|
||||
int findByPos(int index, SDL_Point pos);
|
||||
int findByPos(int index, SDL_FPoint pos);
|
||||
|
||||
// Constructor
|
||||
ItemTracker() = default;
|
||||
@@ -47,8 +47,8 @@ class ItemTracker {
|
||||
static ItemTracker* get();
|
||||
|
||||
// Comprueba si el objeto ya ha sido cogido
|
||||
bool hasBeenPicked(const std::string& name, SDL_Point pos);
|
||||
bool hasBeenPicked(const std::string& name, SDL_FPoint pos);
|
||||
|
||||
// Añade el objeto a la lista de objetos cogidos
|
||||
void addItem(const std::string& name, SDL_Point pos);
|
||||
void addItem(const std::string& name, SDL_FPoint pos);
|
||||
};
|
||||
@@ -7,10 +7,10 @@ Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió
|
||||
bool cursor_visible = true; // Estado del cursor
|
||||
|
||||
void handleEvent(const SDL_Event& event) {
|
||||
if (event.type == SDL_MOUSEMOTION) {
|
||||
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
||||
last_mouse_move_time = SDL_GetTicks();
|
||||
if (!cursor_visible) {
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
SDL_ShowCursor();
|
||||
cursor_visible = true;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ void handleEvent(const SDL_Event& event) {
|
||||
void updateCursorVisibility() {
|
||||
Uint32 current_time = SDL_GetTicks();
|
||||
if (cursor_visible && (current_time - last_mouse_move_time > cursor_hide_time)) {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_HideCursor();
|
||||
cursor_visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ bool saveOptionsToFile(const std::string& file_path) {
|
||||
|
||||
file << "\n## VIDEO\n";
|
||||
file << "# Modo de video: 0 = Ventana, 1 = Pantalla completa, 2 = Pantalla completa (escritorio)\n";
|
||||
file << "video.mode " << options.video.mode << "\n\n";
|
||||
file << "video.mode " << options.video.fullscreen << "\n\n";
|
||||
file << "# Filtro de pantalla: 0 = Nearest, 1 = Linear\n";
|
||||
file << "video.filter " << static_cast<int>(options.video.filter) << "\n\n";
|
||||
file << "# Shaders: 1 = Activado, 0 = Desactivado\n";
|
||||
@@ -176,14 +176,7 @@ bool setOptions(const std::string& var, const std::string& value) {
|
||||
options.window.zoom = DEFAULT_WINDOW_ZOOM;
|
||||
}
|
||||
}},
|
||||
{"video.mode", [](const std::string& v) {
|
||||
int val = safeStoi(v, 0);
|
||||
if (val == 0 || val == SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
options.video.mode = val;
|
||||
} else {
|
||||
options.video.mode = 0;
|
||||
}
|
||||
}},
|
||||
{"video.mode", [](const std::string& v) { options.video.fullscreen = stringToBool(v); }},
|
||||
{"video.filter", [](const std::string& v) {
|
||||
int val = safeStoi(v, static_cast<int>(DEFAULT_VIDEO_FILTER));
|
||||
if (val == static_cast<int>(ScreenFilter::NEAREST) || val == static_cast<int>(ScreenFilter::LINEAR)) {
|
||||
|
||||
@@ -58,7 +58,7 @@ enum class ControlScheme {
|
||||
constexpr int DEFAULT_GAME_WIDTH = 256; // Ancho de la ventana por defecto
|
||||
constexpr int DEFAULT_GAME_HEIGHT = 192; // Alto de la ventana por defecto
|
||||
constexpr int DEFAULT_WINDOW_ZOOM = 2; // Zoom de la ventana por defecto
|
||||
constexpr int DEFAULT_VIDEO_MODE = 0; // Modo de pantalla completa por defecto
|
||||
constexpr bool DEFAULT_VIDEO_MODE = false; // Modo de pantalla completa por defecto
|
||||
constexpr ScreenFilter DEFAULT_VIDEO_FILTER = ScreenFilter::NEAREST; // Filtro por defecto
|
||||
constexpr bool DEFAULT_VIDEO_VERTICAL_SYNC = true; // Vsync activado por defecto
|
||||
constexpr bool DEFAULT_VIDEO_SHADERS = false; // Shaders desactivados por defecto
|
||||
@@ -225,8 +225,8 @@ struct OptionsWindow {
|
||||
// Estructura para gestionar el borde de la pantalla
|
||||
struct Border {
|
||||
bool enabled; // Indica si se ha de mostrar el borde
|
||||
int width; // Ancho del borde
|
||||
int height; // Alto del borde
|
||||
float width; // Ancho del borde
|
||||
float height; // Alto del borde
|
||||
|
||||
// Constructor por defecto
|
||||
Border()
|
||||
@@ -235,7 +235,7 @@ struct Border {
|
||||
height(DEFAULT_BORDER_HEIGHT) {}
|
||||
|
||||
// Constructor
|
||||
Border(bool e, int w, int h)
|
||||
Border(bool e, float w, float h)
|
||||
: enabled(e),
|
||||
width(w),
|
||||
height(h) {}
|
||||
@@ -243,7 +243,7 @@ struct Border {
|
||||
|
||||
// Estructura para las opciones de video
|
||||
struct OptionsVideo {
|
||||
Uint32 mode; // Contiene el valor del modo de pantalla completa
|
||||
bool fullscreen; // Contiene el valor del modo de pantalla completa
|
||||
ScreenFilter filter; // Filtro usado para el escalado de la imagen
|
||||
bool vertical_sync; // Indica si se quiere usar vsync o no
|
||||
bool shaders; // Indica si se van a usar shaders o no
|
||||
@@ -254,7 +254,7 @@ struct OptionsVideo {
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsVideo()
|
||||
: mode(DEFAULT_VIDEO_MODE),
|
||||
: fullscreen(DEFAULT_VIDEO_MODE),
|
||||
filter(DEFAULT_VIDEO_FILTER),
|
||||
vertical_sync(DEFAULT_VIDEO_VERTICAL_SYNC),
|
||||
shaders(DEFAULT_VIDEO_SHADERS),
|
||||
@@ -265,7 +265,7 @@ struct OptionsVideo {
|
||||
|
||||
// Constructor
|
||||
OptionsVideo(Uint32 m, ScreenFilter f, bool vs, bool s, bool is, bool ka, Border b, const std::string& p)
|
||||
: mode(m),
|
||||
: fullscreen(m),
|
||||
filter(f),
|
||||
vertical_sync(vs),
|
||||
shaders(s),
|
||||
@@ -353,8 +353,8 @@ struct OptionsAudio {
|
||||
|
||||
// Estructura para las opciones de juego
|
||||
struct OptionsGame {
|
||||
int width; // Ancho de la resolucion del juego
|
||||
int height; // Alto de la resolucion del juego
|
||||
float width; // Ancho de la resolucion del juego
|
||||
float height; // Alto de la resolucion del juego
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsGame()
|
||||
@@ -362,7 +362,7 @@ struct OptionsGame {
|
||||
height(DEFAULT_GAME_HEIGHT) {}
|
||||
|
||||
// Constructor
|
||||
OptionsGame(int w, int h)
|
||||
OptionsGame(float w, float h)
|
||||
: width(w),
|
||||
height(h) {}
|
||||
};
|
||||
|
||||
@@ -217,7 +217,7 @@ void Player::applyGravity() {
|
||||
|
||||
// Recalcula la posición del jugador y su animación
|
||||
void Player::move() {
|
||||
last_position_ = {static_cast<int>(x_), static_cast<int>(y_)}; // Guarda la posicion actual antes de modificarla
|
||||
last_position_ = {x_, y_}; // Guarda la posicion actual antes de modificarla
|
||||
applyGravity(); // Aplica gravedad al jugador
|
||||
checkState(); // Comprueba el estado del jugador
|
||||
|
||||
@@ -228,7 +228,7 @@ void Player::move() {
|
||||
// Se mueve hacia la izquierda
|
||||
if (vx_ < 0.0f) {
|
||||
// Crea el rectangulo de proyección en el eje X para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
SDL_FRect proj;
|
||||
proj.x = static_cast<int>(x_ + vx_);
|
||||
proj.y = static_cast<int>(y_);
|
||||
proj.h = HEIGHT_;
|
||||
@@ -268,7 +268,7 @@ void Player::move() {
|
||||
// Se mueve hacia la derecha
|
||||
else if (vx_ > 0.0f) {
|
||||
// Crea el rectangulo de proyección en el eje X para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
SDL_FRect proj;
|
||||
proj.x = static_cast<int>(x_) + WIDTH_;
|
||||
proj.y = static_cast<int>(y_);
|
||||
proj.h = HEIGHT_;
|
||||
@@ -322,7 +322,7 @@ void Player::move() {
|
||||
// Se mueve hacia arriba
|
||||
if (vy_ < 0.0f) {
|
||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
SDL_FRect proj;
|
||||
proj.x = static_cast<int>(x_);
|
||||
proj.y = static_cast<int>(y_ + vy_);
|
||||
proj.h = static_cast<int>(std::ceil(std::fabs(vy_))); // Para evitar que tenga una altura de 0 pixels
|
||||
@@ -349,7 +349,7 @@ void Player::move() {
|
||||
// Se mueve hacia abajo
|
||||
else if (vy_ > 0.0f) {
|
||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
SDL_FRect proj;
|
||||
proj.x = static_cast<int>(x_);
|
||||
proj.y = static_cast<int>(y_) + HEIGHT_;
|
||||
proj.h = ceil(vy_); // Para evitar que tenga una altura de 0 pixels
|
||||
@@ -360,7 +360,7 @@ void Player::move() {
|
||||
#endif
|
||||
|
||||
// Comprueba la colisión con las superficies normales y las automáticas
|
||||
const int POS = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj));
|
||||
const float POS = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj));
|
||||
if (POS > -1) {
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||
y_ = POS - HEIGHT_;
|
||||
@@ -373,7 +373,7 @@ void Player::move() {
|
||||
if (state_ != PlayerState::JUMPING) { // Las rampas no se miran si se está saltando
|
||||
const LineVertical LEFT_SIDE = {proj.x, proj.y, proj.y + proj.h - 1};
|
||||
const LineVertical RIGHT_SIDE = {proj.x + proj.w - 1, proj.y, proj.y + proj.h - 1};
|
||||
const int POINT = std::max(room_->checkRightSlopes(&RIGHT_SIDE), room_->checkLeftSlopes(&LEFT_SIDE));
|
||||
const float POINT = std::max(room_->checkRightSlopes(&RIGHT_SIDE), room_->checkLeftSlopes(&LEFT_SIDE));
|
||||
if (POINT > -1) {
|
||||
// No está saltando y hay colisión con una rampa
|
||||
// Calcula la nueva posición
|
||||
@@ -381,7 +381,7 @@ void Player::move() {
|
||||
setState(PlayerState::STANDING);
|
||||
#ifdef DEBUG
|
||||
debug_color_ = static_cast<Uint8>(PaletteColor::YELLOW);
|
||||
debug_point_ = {(int)x_ + (WIDTH_ / 2), POINT};
|
||||
debug_point_ = {x_ + (WIDTH_ / 2), POINT};
|
||||
#endif
|
||||
} else {
|
||||
// No está saltando y no hay colisón con una rampa
|
||||
@@ -559,7 +559,7 @@ void Player::setColor() {
|
||||
|
||||
// Actualiza los puntos de colisión
|
||||
void Player::updateColliderPoints() {
|
||||
const SDL_Rect rect = getRect();
|
||||
const SDL_FRect rect = getRect();
|
||||
collider_points_[0] = {rect.x, rect.y};
|
||||
collider_points_[1] = {rect.x + 7, rect.y};
|
||||
collider_points_[2] = {rect.x + 7, rect.y + 7};
|
||||
@@ -572,7 +572,7 @@ void Player::updateColliderPoints() {
|
||||
|
||||
// Actualiza los puntos de los pies
|
||||
void Player::updateFeet() {
|
||||
const SDL_Point p = {static_cast<int>(x_), static_cast<int>(y_)};
|
||||
const SDL_FPoint p = {x_, y_};
|
||||
|
||||
under_feet_[0] = {p.x, p.y + HEIGHT_};
|
||||
under_feet_[1] = {p.x + 7, p.y + HEIGHT_};
|
||||
@@ -637,7 +637,7 @@ void Player::renderDebugInfo() {
|
||||
surface->putPixel(under_feet_[1].x, under_feet_[1].y, static_cast<Uint8>(PaletteColor::BRIGHT_MAGENTA));
|
||||
|
||||
// Pinta rectangulo del jugador
|
||||
SDL_Rect rect = getRect();
|
||||
SDL_FRect rect = getRect();
|
||||
surface->drawRectBorder(&rect, static_cast<Uint8>(PaletteColor::BRIGHT_CYAN));
|
||||
|
||||
// Pinta el rectangulo de movimiento
|
||||
|
||||
@@ -25,7 +25,7 @@ struct PlayerSpawn {
|
||||
float vy;
|
||||
int jump_init_pos;
|
||||
PlayerState state;
|
||||
SDL_RendererFlip flip;
|
||||
SDL_FlipMode flip;
|
||||
|
||||
// Constructor por defecto
|
||||
PlayerSpawn()
|
||||
@@ -38,7 +38,7 @@ struct PlayerSpawn {
|
||||
flip(SDL_FLIP_NONE) {}
|
||||
|
||||
// Constructor
|
||||
PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_RendererFlip flip)
|
||||
PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_FlipMode flip)
|
||||
: x(x),
|
||||
y(y),
|
||||
vx(vx),
|
||||
@@ -75,34 +75,34 @@ class Player {
|
||||
std::shared_ptr<SAnimatedSprite> sprite_; // Sprite del jugador
|
||||
|
||||
// Variables
|
||||
float x_; // Posición del jugador en el eje X
|
||||
float y_; // Posición del jugador en el eje Y
|
||||
float vx_; // Velocidad/desplazamiento del jugador en el eje X
|
||||
float vy_; // Velocidad/desplazamiento del jugador en el eje Y
|
||||
Uint8 color_; // Color del jugador
|
||||
SDL_Rect collider_box_; // Caja de colisión con los enemigos u objetos
|
||||
std::vector<SDL_Point> collider_points_; // Puntos de colisión con el mapa
|
||||
std::vector<SDL_Point> under_feet_; // Contiene los puntos que hay bajo cada pie del jugador
|
||||
std::vector<SDL_Point> feet_; // Contiene los puntos que hay en el pie del jugador
|
||||
PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
|
||||
PlayerState previous_state_; // Estado previo en el que se encontraba el jugador
|
||||
bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||
bool is_alive_ = true; // Indica si el jugador esta vivo o no
|
||||
bool is_paused_ = false; // Indica si el jugador esta en modo pausa
|
||||
bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica
|
||||
RoomBorder border_ = RoomBorder::TOP; // Indica en cual de los cuatro bordes se encuentra
|
||||
SDL_Rect last_position_; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
|
||||
int jump_init_pos_; // Valor del eje Y en el que se inicia el salto
|
||||
std::vector<JA_Sound_t*> jumping_sound_; // Vecor con todos los sonidos del salto
|
||||
std::vector<JA_Sound_t*> falling_sound_; // Vecor con todos los sonidos de la caída
|
||||
int jumping_counter_ = 0; // Cuenta el tiempo de salto
|
||||
int falling_counter_ = 0; // Cuenta el tiempo de caida
|
||||
float x_; // Posición del jugador en el eje X
|
||||
float y_; // Posición del jugador en el eje Y
|
||||
float vx_; // Velocidad/desplazamiento del jugador en el eje X
|
||||
float vy_; // Velocidad/desplazamiento del jugador en el eje Y
|
||||
Uint8 color_; // Color del jugador
|
||||
SDL_FRect collider_box_; // Caja de colisión con los enemigos u objetos
|
||||
std::vector<SDL_FPoint> collider_points_; // Puntos de colisión con el mapa
|
||||
std::vector<SDL_FPoint> under_feet_; // Contiene los puntos que hay bajo cada pie del jugador
|
||||
std::vector<SDL_FPoint> feet_; // Contiene los puntos que hay en el pie del jugador
|
||||
PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
|
||||
PlayerState previous_state_; // Estado previo en el que se encontraba el jugador
|
||||
bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||
bool is_alive_ = true; // Indica si el jugador esta vivo o no
|
||||
bool is_paused_ = false; // Indica si el jugador esta en modo pausa
|
||||
bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica
|
||||
RoomBorder border_ = RoomBorder::TOP; // Indica en cual de los cuatro bordes se encuentra
|
||||
SDL_FRect last_position_; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
|
||||
int jump_init_pos_; // Valor del eje Y en el que se inicia el salto
|
||||
std::vector<JA_Sound_t*> jumping_sound_; // Vecor con todos los sonidos del salto
|
||||
std::vector<JA_Sound_t*> falling_sound_; // Vecor con todos los sonidos de la caída
|
||||
int jumping_counter_ = 0; // Cuenta el tiempo de salto
|
||||
int falling_counter_ = 0; // Cuenta el tiempo de caida
|
||||
|
||||
#ifdef DEBUG
|
||||
SDL_Rect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug
|
||||
SDL_Rect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug
|
||||
Uint8 debug_color_; // Color del recuadro de debug del jugador
|
||||
SDL_Point debug_point_; // Punto para debug
|
||||
SDL_FRect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug
|
||||
SDL_FRect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug
|
||||
Uint8 debug_color_; // Color del recuadro de debug del jugador
|
||||
SDL_FPoint debug_point_; // Punto para debug
|
||||
#endif
|
||||
|
||||
// Comprueba las entradas y modifica variables
|
||||
@@ -193,10 +193,10 @@ class Player {
|
||||
void switchBorders();
|
||||
|
||||
// Obtiene el rectangulo que delimita al jugador
|
||||
SDL_Rect getRect() { return {static_cast<int>(x_), static_cast<int>(y_), WIDTH_, HEIGHT_}; }
|
||||
SDL_FRect getRect() { return {static_cast<int>(x_), static_cast<int>(y_), WIDTH_, HEIGHT_}; }
|
||||
|
||||
// Obtiene el rectangulo de colision del jugador
|
||||
SDL_Rect& getCollider() { return collider_box_; }
|
||||
SDL_FRect& getCollider() { return collider_box_; }
|
||||
|
||||
// Obtiene el estado de reaparición del jugador
|
||||
PlayerSpawn getSpawnParams() { return {x_, y_, vx_, vy_, jump_init_pos_, state_, sprite_->getFlip()}; }
|
||||
|
||||
@@ -373,20 +373,20 @@ void Resource::calculateTotal() {
|
||||
|
||||
// Muestra el progreso de carga
|
||||
void Resource::renderProgress() {
|
||||
constexpr int X_PADDING = 10;
|
||||
constexpr int Y_PADDING = 10;
|
||||
constexpr int BAR_HEIGHT = 10;
|
||||
const int bar_position = options.game.height - BAR_HEIGHT - Y_PADDING;
|
||||
constexpr float X_PADDING = 10;
|
||||
constexpr float Y_PADDING = 10;
|
||||
constexpr float BAR_HEIGHT = 10;
|
||||
const float bar_position = options.game.height - BAR_HEIGHT - Y_PADDING;
|
||||
Screen::get()->start();
|
||||
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
auto surface = Screen::get()->getRendererSurface();
|
||||
const int wired_bar_width = options.game.width - (X_PADDING * 2);
|
||||
SDL_Rect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING};
|
||||
const float WIRED_BAR_WIDTH = options.game.width - (X_PADDING * 2);
|
||||
SDL_FRect rect_wired = {X_PADDING, bar_position, WIRED_BAR_WIDTH, X_PADDING};
|
||||
surface->drawRectBorder(&rect_wired, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
|
||||
const int full_bar_width = wired_bar_width * count_.getPercentage();
|
||||
SDL_Rect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING};
|
||||
const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * count_.getPercentage();
|
||||
SDL_FRect rect_full = {X_PADDING, bar_position, FULL_BAR_WIDTH, X_PADDING};
|
||||
surface->fillRect(&rect_full, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
|
||||
Screen::get()->render();
|
||||
@@ -397,11 +397,11 @@ void Resource::checkEvents() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
case SDL_EVENT_QUIT:
|
||||
exit(0);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (event.key.key == SDLK_ESCAPE) {
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -338,7 +338,7 @@ void Room::initializeRoom(const RoomData& room) {
|
||||
|
||||
// Crear los items
|
||||
for (const auto& item : room.items) {
|
||||
const SDL_Point itemPos = {item.x, item.y};
|
||||
const SDL_FPoint itemPos = {item.x, item.y};
|
||||
|
||||
if (!ItemTracker::get()->hasBeenPicked(room.name, itemPos)) {
|
||||
// Crear una copia local de los datos del item
|
||||
@@ -361,7 +361,7 @@ void Room::fillMapTexture() {
|
||||
|
||||
// Los tileSetFiles son de 20x20 tiles. El primer tile es el 0. Cuentan hacia la derecha y hacia abajo
|
||||
|
||||
SDL_Rect clip = {0, 0, TILE_SIZE_, TILE_SIZE_};
|
||||
SDL_FRect clip = {0, 0, TILE_SIZE_, TILE_SIZE_};
|
||||
for (int y = 0; y < MAP_HEIGHT_; ++y)
|
||||
for (int x = 0; x < MAP_WIDTH_; ++x) {
|
||||
// Tiled pone los tiles vacios del mapa como cero y empieza a contar de 1 a n.
|
||||
@@ -439,7 +439,7 @@ void Room::fillMapTexture() {
|
||||
// Dibuja el mapa en pantalla
|
||||
void Room::renderMap() {
|
||||
// Dibuja la textura con el mapa en pantalla
|
||||
SDL_Rect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT};
|
||||
SDL_FRect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT};
|
||||
map_surface_->render(nullptr, &dest);
|
||||
|
||||
// Dibuja los tiles animados
|
||||
@@ -516,7 +516,7 @@ std::string Room::getRoom(RoomBorder border) {
|
||||
}
|
||||
|
||||
// Devuelve el tipo de tile que hay en ese pixel
|
||||
TileType Room::getTile(SDL_Point point) {
|
||||
TileType Room::getTile(SDL_FPoint point) {
|
||||
const int pos = ((point.y / TILE_SIZE_) * MAP_WIDTH_) + (point.x / TILE_SIZE_);
|
||||
return getTile(pos);
|
||||
}
|
||||
@@ -562,7 +562,7 @@ TileType Room::getTile(int index) {
|
||||
}
|
||||
|
||||
// Indica si hay colision con un enemigo a partir de un rectangulo
|
||||
bool Room::enemyCollision(SDL_Rect& rect) {
|
||||
bool Room::enemyCollision(SDL_FRect& rect) {
|
||||
for (const auto& enemy : enemies_) {
|
||||
if (checkCollision(rect, enemy->getCollider())) {
|
||||
return true;
|
||||
@@ -572,7 +572,7 @@ bool Room::enemyCollision(SDL_Rect& rect) {
|
||||
}
|
||||
|
||||
// Indica si hay colision con un objeto a partir de un rectangulo
|
||||
bool Room::itemCollision(SDL_Rect& rect) {
|
||||
bool Room::itemCollision(SDL_FRect& rect) {
|
||||
for (int i = 0; i < static_cast<int>(items_.size()); ++i) {
|
||||
if (checkCollision(rect, items_.at(i)->getCollider())) {
|
||||
ItemTracker::get()->addItem(name_, items_.at(i)->getPos());
|
||||
@@ -588,7 +588,7 @@ bool Room::itemCollision(SDL_Rect& rect) {
|
||||
}
|
||||
|
||||
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
|
||||
int Room::getSlopeHeight(SDL_Point p, TileType slope) {
|
||||
int Room::getSlopeHeight(SDL_FPoint p, TileType slope) {
|
||||
// Calcula la base del tile
|
||||
int base = ((p.y / TILE_SIZE_) * TILE_SIZE_) + TILE_SIZE_;
|
||||
#ifdef DEBUG
|
||||
@@ -596,7 +596,7 @@ int Room::getSlopeHeight(SDL_Point p, TileType slope) {
|
||||
#endif
|
||||
|
||||
// Calcula cuanto se ha entrado en el tile horizontalmente
|
||||
const int pos = (p.x % TILE_SIZE_); // Esto da un valor entre 0 y 7
|
||||
const int pos = (static_cast<int>(p.x) % TILE_SIZE_); // Esto da un valor entre 0 y 7
|
||||
#ifdef DEBUG
|
||||
Debug::get()->add("POS = " + std::to_string(pos));
|
||||
#endif
|
||||
@@ -950,7 +950,7 @@ void Room::updateAnimatedTiles() {
|
||||
}
|
||||
|
||||
for (auto& a : animated_tiles_) {
|
||||
SDL_Rect rect = a.sprite->getClip();
|
||||
SDL_FRect rect = a.sprite->getClip();
|
||||
rect.x = a.x_orig + offset;
|
||||
a.sprite->setClip(rect);
|
||||
}
|
||||
@@ -964,7 +964,7 @@ void Room::renderAnimatedTiles() {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
int Room::checkRightSurfaces(SDL_Rect* rect) {
|
||||
int Room::checkRightSurfaces(SDL_FRect* rect) {
|
||||
for (const auto& s : right_walls_) {
|
||||
if (checkCollision(s, *rect)) {
|
||||
return s.x;
|
||||
@@ -975,7 +975,7 @@ int Room::checkRightSurfaces(SDL_Rect* rect) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
int Room::checkLeftSurfaces(SDL_Rect* rect) {
|
||||
int Room::checkLeftSurfaces(SDL_FRect* rect) {
|
||||
for (const auto& s : left_walls_) {
|
||||
if (checkCollision(s, *rect)) {
|
||||
return s.x;
|
||||
@@ -986,7 +986,7 @@ int Room::checkLeftSurfaces(SDL_Rect* rect) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
int Room::checkTopSurfaces(SDL_Rect* rect) {
|
||||
int Room::checkTopSurfaces(SDL_FRect* rect) {
|
||||
for (const auto& s : top_floors_) {
|
||||
if (checkCollision(s, *rect)) {
|
||||
return s.y;
|
||||
@@ -997,7 +997,7 @@ int Room::checkTopSurfaces(SDL_Rect* rect) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
int Room::checkBottomSurfaces(SDL_Rect* rect) {
|
||||
int Room::checkBottomSurfaces(SDL_FRect* rect) {
|
||||
for (const auto& s : bottom_floors_) {
|
||||
if (checkCollision(s, *rect)) {
|
||||
return s.y;
|
||||
@@ -1008,7 +1008,7 @@ int Room::checkBottomSurfaces(SDL_Rect* rect) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
int Room::checkAutoSurfaces(SDL_Rect* rect) {
|
||||
int Room::checkAutoSurfaces(SDL_FRect* rect) {
|
||||
for (const auto& s : conveyor_belt_floors_) {
|
||||
if (checkCollision(s, *rect)) {
|
||||
return s.y;
|
||||
@@ -1019,7 +1019,7 @@ int Room::checkAutoSurfaces(SDL_Rect* rect) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool Room::checkTopSurfaces(SDL_Point* p) {
|
||||
bool Room::checkTopSurfaces(SDL_FPoint* p) {
|
||||
for (const auto& s : top_floors_) {
|
||||
if (checkCollision(s, *p)) {
|
||||
return true;
|
||||
@@ -1030,7 +1030,7 @@ bool Room::checkTopSurfaces(SDL_Point* p) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool Room::checkAutoSurfaces(SDL_Point* p) {
|
||||
bool Room::checkAutoSurfaces(SDL_FPoint* p) {
|
||||
for (const auto& s : conveyor_belt_floors_) {
|
||||
if (checkCollision(s, *p)) {
|
||||
return true;
|
||||
@@ -1043,7 +1043,7 @@ bool Room::checkAutoSurfaces(SDL_Point* p) {
|
||||
// Comprueba las colisiones
|
||||
int Room::checkLeftSlopes(const LineVertical* line) {
|
||||
for (const auto& slope : left_slopes_) {
|
||||
const SDL_Point p = checkCollision(slope, *line);
|
||||
const SDL_FPoint p = checkCollision(slope, *line);
|
||||
if (p.x != -1) {
|
||||
return p.y;
|
||||
}
|
||||
@@ -1053,7 +1053,7 @@ int Room::checkLeftSlopes(const LineVertical* line) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool Room::checkLeftSlopes(SDL_Point* p) {
|
||||
bool Room::checkLeftSlopes(SDL_FPoint* p) {
|
||||
for (const auto& slope : left_slopes_) {
|
||||
if (checkCollision(*p, slope)) {
|
||||
return true;
|
||||
@@ -1066,7 +1066,7 @@ bool Room::checkLeftSlopes(SDL_Point* p) {
|
||||
// Comprueba las colisiones
|
||||
int Room::checkRightSlopes(const LineVertical* line) {
|
||||
for (const auto& slope : right_slopes_) {
|
||||
const SDL_Point p = checkCollision(slope, *line);
|
||||
const SDL_FPoint p = checkCollision(slope, *line);
|
||||
if (p.x != -1) {
|
||||
return p.y;
|
||||
}
|
||||
@@ -1076,7 +1076,7 @@ int Room::checkRightSlopes(const LineVertical* line) {
|
||||
}
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool Room::checkRightSlopes(SDL_Point* p) {
|
||||
bool Room::checkRightSlopes(SDL_FPoint* p) {
|
||||
for (const auto& slope : right_slopes_) {
|
||||
if (checkCollision(*p, slope)) {
|
||||
return true;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
#include <vector> // Para vector
|
||||
@@ -187,52 +186,52 @@ class Room {
|
||||
std::string getRoom(RoomBorder border);
|
||||
|
||||
// Devuelve el tipo de tile que hay en ese pixel
|
||||
TileType getTile(SDL_Point point);
|
||||
TileType getTile(SDL_FPoint point);
|
||||
|
||||
// Indica si hay colision con un enemigo a partir de un rectangulo
|
||||
bool enemyCollision(SDL_Rect& rect);
|
||||
bool enemyCollision(SDL_FRect& rect);
|
||||
|
||||
// Indica si hay colision con un objeto a partir de un rectangulo
|
||||
bool itemCollision(SDL_Rect& rect);
|
||||
bool itemCollision(SDL_FRect& rect);
|
||||
|
||||
// Obten el tamaño del tile
|
||||
int getTileSize() const { return TILE_SIZE_; }
|
||||
|
||||
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
|
||||
int getSlopeHeight(SDL_Point p, TileType slope);
|
||||
int getSlopeHeight(SDL_FPoint p, TileType slope);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkRightSurfaces(SDL_Rect* rect);
|
||||
int checkRightSurfaces(SDL_FRect* rect);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkLeftSurfaces(SDL_Rect* rect);
|
||||
int checkLeftSurfaces(SDL_FRect* rect);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkTopSurfaces(SDL_Rect* rect);
|
||||
int checkTopSurfaces(SDL_FRect* rect);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkBottomSurfaces(SDL_Rect* rect);
|
||||
int checkBottomSurfaces(SDL_FRect* rect);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkAutoSurfaces(SDL_Rect* rect);
|
||||
int checkAutoSurfaces(SDL_FRect* rect);
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool checkTopSurfaces(SDL_Point* p);
|
||||
bool checkTopSurfaces(SDL_FPoint* p);
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool checkAutoSurfaces(SDL_Point* p);
|
||||
bool checkAutoSurfaces(SDL_FPoint* p);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkLeftSlopes(const LineVertical* line);
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool checkLeftSlopes(SDL_Point* p);
|
||||
bool checkLeftSlopes(SDL_FPoint* p);
|
||||
|
||||
// Comprueba las colisiones
|
||||
int checkRightSlopes(const LineVertical* line);
|
||||
|
||||
// Comprueba las colisiones
|
||||
bool checkRightSlopes(SDL_Point* p);
|
||||
bool checkRightSlopes(SDL_FPoint* p);
|
||||
|
||||
// Pone el mapa en modo pausa
|
||||
void setPaused(bool value) { is_paused_ = value; };
|
||||
|
||||
@@ -141,7 +141,7 @@ void Scoreboard::fillTexture() {
|
||||
// Muestra si suena la música
|
||||
if (data_->music) {
|
||||
const Uint8 c = data_->color;
|
||||
SDL_Rect clip = {0, 8, 8, 8};
|
||||
SDL_FRect clip = {0, 8, 8, 8};
|
||||
item_surface_->renderWithColorReplace(20 * BLOCK, LINE2, 1, c, &clip);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class Scoreboard {
|
||||
Uint32 paused_time_elapsed_; // Tiempo acumulado en pausa
|
||||
ClockData clock_; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
|
||||
Uint8 items_color_; // Color de la cantidad de items recogidos
|
||||
SDL_Rect surface_dest_; // Rectangulo donde dibujar la surface del marcador
|
||||
SDL_FRect surface_dest_; // Rectangulo donde dibujar la surface del marcador
|
||||
|
||||
// Obtiene el tiempo transcurrido de partida
|
||||
ClockData getTime();
|
||||
|
||||
@@ -42,9 +42,8 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
renderer_(renderer),
|
||||
palettes_(Asset::get()->getListByType(AssetType::PALETTE)) {
|
||||
// Inicializa variables
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetCurrentDisplayMode(0, &DM);
|
||||
info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ";
|
||||
auto display_mode = SDL_GetCurrentDisplayMode(0);
|
||||
info_resolution_ = std::to_string(display_mode->w) + " X " + std::to_string(display_mode->h) + " AT " + std::to_string(display_mode->refresh_rate) + " HZ";
|
||||
|
||||
// Ajusta los tamaños
|
||||
game_surface_dstrect_ = {options.video.border.width, options.video.border.height, options.game.width, options.game.height};
|
||||
@@ -54,9 +53,6 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
// Define el color del borde para el modo de pantalla completa
|
||||
border_color_ = static_cast<Uint8>(PaletteColor::BLACK);
|
||||
|
||||
// Establece el modo de escalado
|
||||
SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
|
||||
|
||||
// Crea la textura donde se dibujan los graficos del juego
|
||||
game_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height);
|
||||
if (!game_texture_) {
|
||||
@@ -65,6 +61,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
std::cerr << "Error: game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
SDL_SetTextureScaleMode(game_texture_, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
// Crea la textura donde se dibuja el borde que rodea el area de juego
|
||||
border_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
|
||||
@@ -74,8 +71,9 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
std::cerr << "Error: border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
SDL_SetTextureScaleMode(border_texture_, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
// Crea la textura donde se dibuja el borde que rodea el area de juego
|
||||
// Crea la textura para los shaders
|
||||
const int EXTRA_WIDTH = options.video.border.enabled ? options.video.border.width * 2 : 0;
|
||||
const int EXTRA_HEIGHT = options.video.border.enabled ? options.video.border.height * 2 : 0;
|
||||
shaders_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + EXTRA_WIDTH, options.game.height + EXTRA_HEIGHT);
|
||||
@@ -85,6 +83,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
std::cerr << "Error: shaders_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
SDL_SetTextureScaleMode(shaders_texture_, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
// Crea la surface donde se dibujan los graficos del juego
|
||||
game_surface_ = std::make_shared<Surface>(options.game.width, options.game.height);
|
||||
@@ -100,7 +99,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
|
||||
renderer_surface_ = std::make_shared<std::shared_ptr<Surface>>(game_surface_);
|
||||
|
||||
// Establece el modo de video
|
||||
setVideoMode(options.video.mode);
|
||||
setVideoMode(options.video.fullscreen);
|
||||
|
||||
// Muestra la ventana
|
||||
show();
|
||||
@@ -141,12 +140,12 @@ void Screen::render() {
|
||||
}
|
||||
|
||||
// Establece el modo de video
|
||||
void Screen::setVideoMode(int mode) {
|
||||
void Screen::setVideoMode(bool mode) {
|
||||
// Actualiza las opciones
|
||||
options.video.mode = mode;
|
||||
options.video.fullscreen = mode;
|
||||
|
||||
// Configura el modo de pantalla y ajusta la ventana
|
||||
SDL_SetWindowFullscreen(window_, options.video.mode);
|
||||
SDL_SetWindowFullscreen(window_, options.video.fullscreen);
|
||||
adjustWindowSize();
|
||||
adjustRenderLogicalSize();
|
||||
|
||||
@@ -156,19 +155,19 @@ void Screen::setVideoMode(int mode) {
|
||||
|
||||
// Camibia entre pantalla completa y ventana
|
||||
void Screen::toggleVideoMode() {
|
||||
options.video.mode = (options.video.mode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
|
||||
setVideoMode(options.video.mode);
|
||||
options.video.fullscreen = !options.video.fullscreen;
|
||||
setVideoMode(options.video.fullscreen);
|
||||
}
|
||||
|
||||
// Reduce el tamaño de la ventana
|
||||
bool Screen::decWindowZoom() {
|
||||
if (options.video.mode == 0) {
|
||||
if (options.video.fullscreen == 0) {
|
||||
const int PREVIOUS_ZOOM = options.window.zoom;
|
||||
--options.window.zoom;
|
||||
options.window.zoom = std::max(options.window.zoom, 1);
|
||||
|
||||
if (options.window.zoom != PREVIOUS_ZOOM) {
|
||||
setVideoMode(options.video.mode);
|
||||
setVideoMode(options.video.fullscreen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -178,13 +177,13 @@ bool Screen::decWindowZoom() {
|
||||
|
||||
// Aumenta el tamaño de la ventana
|
||||
bool Screen::incWindowZoom() {
|
||||
if (options.video.mode == 0) {
|
||||
if (options.video.fullscreen == 0) {
|
||||
const int PREVIOUS_ZOOM = options.window.zoom;
|
||||
++options.window.zoom;
|
||||
options.window.zoom = std::min(options.window.zoom, options.window.max_zoom);
|
||||
|
||||
if (options.window.zoom != PREVIOUS_ZOOM) {
|
||||
setVideoMode(options.video.mode);
|
||||
setVideoMode(options.video.fullscreen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +201,7 @@ void Screen::setBorderColor(Uint8 color) {
|
||||
void Screen::toggleBorder() {
|
||||
options.video.border.enabled = !options.video.border.enabled;
|
||||
createShadersTexture();
|
||||
setVideoMode(options.video.mode);
|
||||
setVideoMode(options.video.fullscreen);
|
||||
}
|
||||
|
||||
// Dibuja las notificaciones
|
||||
@@ -215,7 +214,7 @@ void Screen::renderNotifications() {
|
||||
// Cambia el estado de los shaders
|
||||
void Screen::toggleShaders() {
|
||||
options.video.shaders = !options.video.shaders;
|
||||
setVideoMode(options.video.mode);
|
||||
setVideoMode(options.video.fullscreen);
|
||||
}
|
||||
|
||||
// Actualiza la lógica de la clase
|
||||
@@ -233,7 +232,7 @@ void Screen::adjustWindowSize() {
|
||||
options.window.max_zoom = getMaxZoom();
|
||||
|
||||
// Establece el nuevo tamaño
|
||||
if (options.video.mode == 0) {
|
||||
if (options.video.fullscreen == 0) {
|
||||
int old_width, old_height;
|
||||
SDL_GetWindowSize(window_, &old_width, &old_height);
|
||||
|
||||
@@ -250,17 +249,16 @@ void Screen::adjustWindowSize() {
|
||||
|
||||
// Ajusta el tamaño lógico del renderizador
|
||||
void Screen::adjustRenderLogicalSize() {
|
||||
SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_);
|
||||
SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_, options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
}
|
||||
|
||||
// Obtiene el tamaño máximo de zoom posible para la ventana
|
||||
int Screen::getMaxZoom() {
|
||||
// Obtiene información sobre la pantalla
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetCurrentDisplayMode(0, &DM);
|
||||
auto display_mode = SDL_GetCurrentDisplayMode(0);
|
||||
|
||||
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
|
||||
const int MAX_ZOOM = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_);
|
||||
const int MAX_ZOOM = std::min(display_mode->w / window_width_, (display_mode->h - WINDOWS_DECORATIONS_) / window_height_);
|
||||
|
||||
// Normaliza los valores de zoom
|
||||
options.window.zoom = std::min(options.window.zoom, MAX_ZOOM);
|
||||
@@ -345,14 +343,14 @@ void Screen::textureToRenderer() {
|
||||
|
||||
if (options.video.shaders) {
|
||||
SDL_SetRenderTarget(renderer_, shaders_texture_);
|
||||
SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr);
|
||||
SDL_RenderTexture(renderer_, texture_to_render, nullptr, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
shader::render();
|
||||
} else {
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr);
|
||||
SDL_RenderTexture(renderer_, texture_to_render, nullptr, nullptr);
|
||||
SDL_RenderPresent(renderer_);
|
||||
}
|
||||
}
|
||||
@@ -432,6 +430,12 @@ void Screen::setNotificationsEnabled(bool value) { notifications_enabled_ = valu
|
||||
// Activa / desactiva la información de debug
|
||||
void Screen::toggleDebugInfo() { show_debug_info_ = !show_debug_info_; }
|
||||
|
||||
// Alterna entre activar y desactivar el escalado entero
|
||||
void Screen::toggleIntegerScale() {
|
||||
options.video.integer_scale = !options.video.integer_scale;
|
||||
SDL_SetRenderLogicalPresentation(renderer_, options.game.width, options.game.height, options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
}
|
||||
|
||||
// Getters
|
||||
SDL_Renderer* Screen::getRenderer() { return renderer_; }
|
||||
std::shared_ptr<Surface> Screen::getRendererSurface() { return (*renderer_surface_); }
|
||||
|
||||
@@ -66,7 +66,7 @@ class Screen {
|
||||
// Variables
|
||||
int window_width_; // Ancho de la pantalla o ventana
|
||||
int window_height_; // Alto de la pantalla o ventana
|
||||
SDL_Rect game_surface_dstrect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
|
||||
SDL_FRect game_surface_dstrect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
|
||||
Uint8 border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
|
||||
std::vector<std::string> palettes_; // Listado de los ficheros de paletta disponibles
|
||||
Uint8 current_palette_ = 0; // Indice para el vector de paletas
|
||||
@@ -145,11 +145,14 @@ class Screen {
|
||||
void update();
|
||||
|
||||
// Establece el modo de video
|
||||
void setVideoMode(int mode);
|
||||
void setVideoMode(bool mode);
|
||||
|
||||
// Camibia entre pantalla completa y ventana
|
||||
void toggleVideoMode();
|
||||
|
||||
// Alterna entre activar y desactivar el escalado entero
|
||||
void toggleIntegerScale();
|
||||
|
||||
// Reduce el tamaño de la ventana
|
||||
bool decWindowZoom();
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ void Credits::fillTexture() {
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 8, 256, 192};
|
||||
SDL_FRect rect = {0, 8, 256, 192};
|
||||
cover_surface_->fillRect(&rect, color);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ void Credits::render() {
|
||||
|
||||
// Dibuja la textura que cubre el texto
|
||||
const int offset = std::min(counter_ / 8, 192 / 2);
|
||||
SDL_Rect srcRect = {0, 0, 256, 192 - (offset * 2)};
|
||||
SDL_FRect srcRect = {0, 0, 256, 192 - (offset * 2)};
|
||||
cover_surface_->render(0, offset * 2, &srcRect);
|
||||
|
||||
// Dibuja el sprite con el brillo
|
||||
|
||||
@@ -190,7 +190,7 @@ void Ending::iniTexts() {
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 8, WIDTH, HEIGHT};
|
||||
SDL_FRect rect = {0, 8, WIDTH, HEIGHT};
|
||||
surface->fillRect(&rect, color);
|
||||
|
||||
// Crea el sprite
|
||||
@@ -256,7 +256,7 @@ void Ending::iniPics() {
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 8, WIDTH, HEIGHT};
|
||||
SDL_FRect rect = {0, 8, WIDTH, HEIGHT};
|
||||
surface->fillRect(&rect, color);
|
||||
|
||||
// Crea el sprite
|
||||
@@ -453,7 +453,7 @@ void Ending::fillCoverTexture() {
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 0, 256, options.game.height};
|
||||
SDL_FRect rect = {0, 0, 256, options.game.height};
|
||||
surface->fillRect(&rect, color);
|
||||
|
||||
Screen::get()->setRendererSurface(previuos_renderer);
|
||||
@@ -464,8 +464,8 @@ void Ending::renderCoverTexture() {
|
||||
if (cover_counter_ > 0) {
|
||||
// Dibuja la textura que cubre el texto
|
||||
const int OFFSET = std::min(cover_counter_, 100);
|
||||
SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, OFFSET * 2};
|
||||
SDL_Rect dstRect = {0, 0, 256, OFFSET * 2};
|
||||
SDL_FRect srcRect = {0, 200 - (cover_counter_ * 2), 256, OFFSET * 2};
|
||||
SDL_FRect dstRect = {0, 0, 256, OFFSET * 2};
|
||||
cover_surface_->render(&srcRect, &dstRect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,20 +343,20 @@ void Ending2::renderTexts() {
|
||||
// Coloca los sprites en su sito
|
||||
void Ending2::placeSprites() {
|
||||
for (int i = 0; i < static_cast<int>(sprites_.size()); ++i) {
|
||||
const int X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
|
||||
const int Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + options.game.height + 40;
|
||||
const int W = sprites_.at(i)->getWidth();
|
||||
const int H = sprites_.at(i)->getHeight();
|
||||
const int DX = -(W / 2);
|
||||
const int DY = sprite_max_height_ - H;
|
||||
const float X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
|
||||
const float Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + options.game.height + 40;
|
||||
const float W = sprites_.at(i)->getWidth();
|
||||
const float H = sprites_.at(i)->getHeight();
|
||||
const float DX = -(W / 2);
|
||||
const float DY = sprite_max_height_ - H;
|
||||
|
||||
sprites_.at(i)->setPos({X + DX, Y + DY, W, H});
|
||||
sprites_.at(i)->setVelY(SPRITE_DESP_SPEED_);
|
||||
}
|
||||
|
||||
// Recoloca el sprite del jugador, que es el último de la lista
|
||||
const int X = (options.game.width - sprites_.back()->getWidth()) / 2;
|
||||
const int Y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
|
||||
const float X = (options.game.width - sprites_.back()->getWidth()) / 2;
|
||||
const float Y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
|
||||
sprites_.back()->setPos(X, Y);
|
||||
sprites_.back()->setCurrentAnimation("walk");
|
||||
}
|
||||
@@ -364,7 +364,7 @@ void Ending2::placeSprites() {
|
||||
// Crea los sprites con las texturas con los textos
|
||||
void Ending2::createSpriteTexts() {
|
||||
// Crea los sprites de texto a partir de la lista
|
||||
for (int i = 0; i < static_cast<int>(sprite_list_.size()); ++i) {
|
||||
for (size_t i = 0; i < sprite_list_.size(); ++i) {
|
||||
auto text = Resource::get()->getText("smb2");
|
||||
|
||||
// Procesa y ajusta el texto del sprite actual
|
||||
@@ -375,16 +375,16 @@ void Ending2::createSpriteTexts() {
|
||||
}
|
||||
|
||||
// Calcula las dimensiones del texto
|
||||
const int W = text->lenght(txt, 1);
|
||||
const int H = text->getCharacterSize();
|
||||
const float W = text->lenght(txt, 1);
|
||||
const float H = text->getCharacterSize();
|
||||
|
||||
// Determina la columna y la posición X del texto
|
||||
const int X = (i == static_cast<int>(sprite_list_.size()) - 1)
|
||||
const float X = (i == sprite_list_.size() - 1)
|
||||
? (GAMECANVAS_CENTER_X - (W / 2))
|
||||
: ((i % 2 == 0 ? FIRST_COL_ : SECOND_COL_) - (W / 2));
|
||||
|
||||
// Calcula la posición Y del texto en base a la posición y altura del sprite
|
||||
const int Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_;
|
||||
const float Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_;
|
||||
|
||||
// Crea la surface
|
||||
auto surface = std::make_shared<Surface>(W, H);
|
||||
@@ -393,7 +393,7 @@ void Ending2::createSpriteTexts() {
|
||||
text->write(0, 0, txt);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {X, Y, W, H};
|
||||
SDL_FRect pos = {X, Y, W, H};
|
||||
sprite_texts_.emplace_back(std::make_shared<SMovingSprite>(surface, pos));
|
||||
sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED_);
|
||||
Screen::get()->setRendererSurface(previuos_renderer);
|
||||
@@ -409,22 +409,22 @@ void Ending2::createTexts() {
|
||||
auto text = Resource::get()->getText("smb2");
|
||||
|
||||
// Crea los sprites de texto a partir de la lista
|
||||
for (int i = 0; i < (int)list.size(); ++i) {
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
// Calcula constantes
|
||||
const int w = text->lenght(list[i], 1);
|
||||
const int h = text->getCharacterSize();
|
||||
const int x = GAMECANVAS_CENTER_X;
|
||||
const int dx = -(w / 2);
|
||||
const int y = options.game.height + (text->getCharacterSize() * (i * 2));
|
||||
const float W = text->lenght(list[i], 1);
|
||||
const float H = text->getCharacterSize();
|
||||
const float X = GAMECANVAS_CENTER_X;
|
||||
const float DX = -(W / 2);
|
||||
const float Y = options.game.height + (text->getCharacterSize() * (i * 2));
|
||||
|
||||
// Crea la surface
|
||||
auto surface = std::make_shared<Surface>(w, h);
|
||||
auto surface = std::make_shared<Surface>(W, H);
|
||||
auto previuos_renderer = Screen::get()->getRendererSurface();
|
||||
Screen::get()->setRendererSurface(surface);
|
||||
text->write(0, 0, list[i]);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {x + dx, y, w, h};
|
||||
SDL_FRect pos = {X + DX, Y, W, H};
|
||||
texts_.emplace_back(std::make_shared<SMovingSprite>(surface, pos));
|
||||
texts_.back()->setVelY(SPRITE_DESP_SPEED_);
|
||||
Screen::get()->setRendererSurface(previuos_renderer);
|
||||
@@ -438,22 +438,22 @@ void Ending2::createTexts() {
|
||||
list.push_back("FOR PLAYING!");
|
||||
|
||||
// Crea los sprites de texto a partir de la lista
|
||||
for (int i = 0; i < (int)list.size(); ++i) {
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
// Calcula constantes
|
||||
const int w = text->lenght(list[i], 1);
|
||||
const int h = text->getCharacterSize();
|
||||
const int x = GAMECANVAS_CENTER_X;
|
||||
const int dx = -(w / 2);
|
||||
const int y = START + (text->getCharacterSize() * (i * 2));
|
||||
const float W = text->lenght(list[i], 1);
|
||||
const float H = text->getCharacterSize();
|
||||
const float X = GAMECANVAS_CENTER_X;
|
||||
const float DX = -(W / 2);
|
||||
const float Y = START + (text->getCharacterSize() * (i * 2));
|
||||
|
||||
// Crea la surface
|
||||
auto surface = std::make_shared<Surface>(w, h);
|
||||
auto surface = std::make_shared<Surface>(W, H);
|
||||
auto previuos_renderer = Screen::get()->getRendererSurface();
|
||||
Screen::get()->setRendererSurface(surface);
|
||||
text->write(0, 0, list[i]);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {x + dx, y, w, h};
|
||||
SDL_FRect pos = {X + DX, Y, W, H};
|
||||
texts_.emplace_back(std::make_shared<SMovingSprite>(surface, pos));
|
||||
texts_.back()->setVelY(SPRITE_DESP_SPEED_);
|
||||
Screen::get()->setRendererSurface(previuos_renderer);
|
||||
|
||||
@@ -70,8 +70,8 @@ class Ending2 {
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
|
||||
std::vector<Uint8> colors_; // Vector con los colores para el fade
|
||||
int sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho
|
||||
int sprite_max_height_ = 0; // El valor de alto del sprite mas alto
|
||||
float sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho
|
||||
float sprite_max_height_ = 0; // El valor de alto del sprite mas alto
|
||||
State state_; // Controla el estado de la clase
|
||||
|
||||
// Actualiza el objeto
|
||||
|
||||
@@ -193,7 +193,7 @@ void Game::renderDebugInfo() {
|
||||
auto surface = Screen::get()->getRendererSurface();
|
||||
|
||||
// Borra el marcador
|
||||
SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
|
||||
SDL_FRect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
|
||||
surface->fillRect(&rect, static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
// Pinta la rejilla
|
||||
|
||||
@@ -63,7 +63,7 @@ class Game {
|
||||
bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
|
||||
int black_screen_counter_ = 0; // Contador para temporizar la pantalla en negro
|
||||
int total_items_; // Cantidad total de items que hay en el mapeado del juego
|
||||
SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
|
||||
SDL_FRect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
|
||||
|
||||
// Actualiza el juego, las variables, comprueba la entrada, etc.
|
||||
void update();
|
||||
|
||||
@@ -16,13 +16,13 @@ class LoadingScreen {
|
||||
std::shared_ptr<Surface> screen_surface_; // Surface para dibujar la pantalla de carga
|
||||
|
||||
// Variables
|
||||
int pre_counter_ = 0; // Contador previo para realizar una pausa inicial
|
||||
int counter_ = 0; // Contador
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
int load_counter_ = 0; // Contador para controlar las cargas
|
||||
bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra
|
||||
int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga
|
||||
SDL_Rect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga
|
||||
int pre_counter_ = 0; // Contador previo para realizar una pausa inicial
|
||||
int counter_ = 0; // Contador
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
int load_counter_ = 0; // Contador para controlar las cargas
|
||||
bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra
|
||||
int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga
|
||||
SDL_FRect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga
|
||||
|
||||
// Actualiza las variables
|
||||
void update();
|
||||
|
||||
@@ -64,9 +64,9 @@ void Title::checkEvents() {
|
||||
globalEvents::check(event);
|
||||
|
||||
// Solo se comprueban estas teclas si no está activo el menu de logros
|
||||
if (event.type == SDL_KEYDOWN) {
|
||||
if (event.type == SDL_EVENT_KEY_DOWN) {
|
||||
if (!show_cheevos_) {
|
||||
switch (event.key.keysym.scancode) {
|
||||
switch (event.key.key) {
|
||||
case SDL_SCANCODE_1:
|
||||
options.section.section = Section::GAME;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
@@ -242,8 +242,8 @@ void Title::moveCheevosList(int direction) {
|
||||
cheevos_surface_view_.y = direction == 0 ? cheevos_surface_view_.y - SPEED : cheevos_surface_view_.y + SPEED;
|
||||
|
||||
// Ajusta los limites
|
||||
const int BOTTOM = cheevos_surface_->getHeight() - cheevos_surface_view_.h;
|
||||
cheevos_surface_view_.y = std::clamp(cheevos_surface_view_.y, 0, BOTTOM);
|
||||
const float BOTTOM = cheevos_surface_->getHeight() - cheevos_surface_view_.h;
|
||||
cheevos_surface_view_.y = std::clamp(cheevos_surface_view_.y, 0.0F, BOTTOM);
|
||||
|
||||
cheevos_sprite_->setClip(cheevos_surface_view_);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class Title {
|
||||
std::vector<TitleLetter> letters_; // Vector con las letras de la marquesina
|
||||
int marquee_speed_ = 2; // Velocidad de desplazamiento de la marquesina
|
||||
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
|
||||
SDL_Rect cheevos_surface_view_; // Zona visible de la surface con el listado de logros
|
||||
SDL_FRect cheevos_surface_view_; // Zona visible de la surface con el listado de logros
|
||||
TitleState state_; // Estado en el que se encuentra el bucle principal
|
||||
|
||||
// Actualiza las variables
|
||||
|
||||
@@ -190,7 +190,7 @@ void SAnimatedSprite::setAnimations(const Animations& animations) {
|
||||
// Se introducen los valores separados por comas en un vector
|
||||
std::stringstream ss(value);
|
||||
std::string tmp;
|
||||
SDL_Rect rect = {0, 0, frame_width, frame_height};
|
||||
SDL_FRect rect = {0, 0, frame_width, frame_height};
|
||||
while (getline(ss, tmp, ',')) {
|
||||
// Comprueba que el tile no sea mayor que el maximo indice permitido
|
||||
const int num_tile = std::stoi(tmp);
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
class Surface; // lines 9-9
|
||||
|
||||
struct AnimationData {
|
||||
std::string name; // Nombre de la animacion
|
||||
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
|
||||
int speed; // Velocidad de la animación
|
||||
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
|
||||
bool completed; // Indica si ha finalizado la animación
|
||||
int current_frame; // Frame actual
|
||||
int counter; // Contador para las animaciones
|
||||
std::string name; // Nombre de la animacion
|
||||
std::vector<SDL_FRect> frames; // Cada uno de los frames que componen la animación
|
||||
int speed; // Velocidad de la animación
|
||||
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
|
||||
bool completed; // Indica si ha finalizado la animación
|
||||
int current_frame; // Frame actual
|
||||
int counter; // Contador para las animaciones
|
||||
|
||||
AnimationData()
|
||||
: name(std::string()),
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#include "surface.h" // Para Surface
|
||||
|
||||
// Constructor
|
||||
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos, SDL_RendererFlip flip)
|
||||
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip)
|
||||
: SSprite(surface, pos),
|
||||
x_(pos.x),
|
||||
y_(pos.y),
|
||||
flip_(flip) { SSprite::pos_ = pos; }
|
||||
|
||||
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos)
|
||||
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
||||
: SSprite(surface, pos),
|
||||
x_(pos.x),
|
||||
y_(pos.y),
|
||||
@@ -65,7 +65,7 @@ void SMovingSprite::render(Uint8 source_color, Uint8 target_color) {
|
||||
}
|
||||
|
||||
// Establece la posición y_ el tamaño del objeto
|
||||
void SMovingSprite::setPos(SDL_Rect rect) {
|
||||
void SMovingSprite::setPos(SDL_FRect rect) {
|
||||
x_ = static_cast<float>(rect.x);
|
||||
y_ = static_cast<float>(rect.y);
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@ class SMovingSprite : public SSprite {
|
||||
float ax_ = 0.0f; // Aceleración en el eje X. Variación de la velocidad
|
||||
float ay_ = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
|
||||
|
||||
SDL_RendererFlip flip_; // Indica como se voltea el sprite
|
||||
SDL_FlipMode flip_; // Indica como se voltea el sprite
|
||||
|
||||
// Mueve el sprite
|
||||
void move();
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos, SDL_RendererFlip flip);
|
||||
SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos);
|
||||
SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
|
||||
SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
|
||||
explicit SMovingSprite(std::shared_ptr<Surface> surface);
|
||||
|
||||
// Destructor
|
||||
@@ -59,16 +59,16 @@ class SMovingSprite : public SSprite {
|
||||
void setAccelY(float value) { ay_ = value; }
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setFlip(SDL_RendererFlip flip) { flip_ = flip; }
|
||||
void setFlip(SDL_FlipMode flip) { flip_ = flip; }
|
||||
|
||||
// Gira el sprite horizontalmente
|
||||
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; }
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
SDL_RendererFlip getFlip() { return flip_; }
|
||||
SDL_FlipMode getFlip() { return flip_; }
|
||||
|
||||
// Establece la posición y_ el tamaño del objeto
|
||||
void setPos(SDL_Rect rect);
|
||||
void setPos(SDL_FRect rect);
|
||||
|
||||
// Establece el valor de las variables
|
||||
void setPos(float x, float y);
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
#include "surface.h" // Para Surface
|
||||
|
||||
// Constructor
|
||||
SSprite::SSprite(std::shared_ptr<Surface> surface, int x, int y, int w, int h)
|
||||
SSprite::SSprite(std::shared_ptr<Surface> surface, float x, float y, float w, float h)
|
||||
: surface_(surface),
|
||||
pos_((SDL_Rect){x, y, w, h}),
|
||||
clip_((SDL_Rect){0, 0, pos_.w, pos_.h}) {}
|
||||
pos_((SDL_FRect){x, y, w, h}),
|
||||
clip_((SDL_FRect){0.0F, 0.0F, pos_.w, pos_.h}) {}
|
||||
|
||||
SSprite::SSprite(std::shared_ptr<Surface> surface, SDL_Rect rect)
|
||||
SSprite::SSprite(std::shared_ptr<Surface> surface, SDL_FRect rect)
|
||||
: surface_(surface),
|
||||
pos_(rect),
|
||||
clip_((SDL_Rect){0, 0, pos_.w, pos_.h}) {}
|
||||
clip_((SDL_FRect){0, 0, pos_.w, pos_.h}) {}
|
||||
|
||||
SSprite::SSprite(std::shared_ptr<Surface> surface)
|
||||
: surface_(surface),
|
||||
pos_({0, 0, surface_->getWidth(), surface_->getHeight()}),
|
||||
pos_((SDL_FRect){0.0F, 0.0F, surface_->getWidth(), surface_->getHeight()}),
|
||||
clip_(pos_) {}
|
||||
|
||||
// Muestra el sprite por pantalla
|
||||
@@ -28,13 +28,13 @@ void SSprite::render(Uint8 source_color, Uint8 target_color) {
|
||||
}
|
||||
|
||||
// Establece la posición del objeto
|
||||
void SSprite::setPosition(int x, int y) {
|
||||
void SSprite::setPosition(float x, float y) {
|
||||
pos_.x = x;
|
||||
pos_.y = y;
|
||||
}
|
||||
|
||||
// Establece la posición del objeto
|
||||
void SSprite::setPosition(SDL_Point p) {
|
||||
void SSprite::setPosition(SDL_FPoint p) {
|
||||
pos_.x = p.x;
|
||||
pos_.y = p.y;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ class SSprite {
|
||||
protected:
|
||||
// Variables
|
||||
std::shared_ptr<Surface> surface_; // Surface donde estan todos los dibujos del sprite
|
||||
SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite
|
||||
SDL_Rect clip_; // Rectangulo de origen de la surface que se dibujará en pantalla
|
||||
SDL_FRect pos_; // Posición y tamaño donde dibujar el sprite
|
||||
SDL_FRect clip_; // Rectangulo de origen de la surface que se dibujará en pantalla
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
SSprite(std::shared_ptr<Surface>, int x, int y, int w, int h);
|
||||
SSprite(std::shared_ptr<Surface>, SDL_Rect rect);
|
||||
SSprite(std::shared_ptr<Surface>, float x, float y, float w, float h);
|
||||
SSprite(std::shared_ptr<Surface>, SDL_FRect rect);
|
||||
explicit SSprite(std::shared_ptr<Surface>);
|
||||
|
||||
// Destructor
|
||||
@@ -30,36 +30,36 @@ class SSprite {
|
||||
virtual void clear();
|
||||
|
||||
// Obtiene la posición y el tamaño
|
||||
int getX() const { return pos_.x; }
|
||||
int getY() const { return pos_.y; }
|
||||
int getWidth() const { return pos_.w; }
|
||||
int getHeight() const { return pos_.h; }
|
||||
float getX() const { return pos_.x; }
|
||||
float getY() const { return pos_.y; }
|
||||
float getWidth() const { return pos_.w; }
|
||||
float getHeight() const { return pos_.h; }
|
||||
|
||||
// Devuelve el rectangulo donde está el sprite
|
||||
SDL_Rect getPosition() const { return pos_; }
|
||||
SDL_Rect& getRect() { return pos_; }
|
||||
SDL_FRect getPosition() const { return pos_; }
|
||||
SDL_FRect& getRect() { return pos_; }
|
||||
|
||||
// Establece la posición y el tamaño
|
||||
void setX(int x) { pos_.x = x; }
|
||||
void setY(int y) { pos_.y = y; }
|
||||
void setWidth(int w) { pos_.w = w; }
|
||||
void setHeight(int h) { pos_.h = h; }
|
||||
void setX(float x) { pos_.x = x; }
|
||||
void setY(float y) { pos_.y = y; }
|
||||
void setWidth(float w) { pos_.w = w; }
|
||||
void setHeight(float h) { pos_.h = h; }
|
||||
|
||||
// Establece la posición del objeto
|
||||
void setPosition(int x, int y);
|
||||
void setPosition(SDL_Point p);
|
||||
void setPosition(SDL_Rect r) { pos_ = r; }
|
||||
void setPosition(float x, float y);
|
||||
void setPosition(SDL_FPoint p);
|
||||
void setPosition(SDL_FRect r) { pos_ = r; }
|
||||
|
||||
// Aumenta o disminuye la posición
|
||||
void incX(int value) { pos_.x += value; }
|
||||
void incY(int value) { pos_.y += value; }
|
||||
void incX(float value) { pos_.x += value; }
|
||||
void incY(float value) { pos_.y += value; }
|
||||
|
||||
// Obtiene el rectangulo que se dibuja de la surface
|
||||
SDL_Rect getClip() const { return clip_; }
|
||||
SDL_FRect getClip() const { return clip_; }
|
||||
|
||||
// Establece el rectangulo que se dibuja de la surface
|
||||
void setClip(SDL_Rect rect) { clip_ = rect; }
|
||||
void setClip(int x, int y, int w, int h) { clip_ = (SDL_Rect){x, y, w, h}; }
|
||||
void setClip(SDL_FRect rect) { clip_ = rect; }
|
||||
void setClip(float x, float y, float w, float h) { clip_ = (SDL_FRect){x, y, w, h}; }
|
||||
|
||||
// Obtiene un puntero a la surface
|
||||
std::shared_ptr<Surface> getSurface() const { return surface_; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// IWYU pragma: no_include <bits/std_abs.h>
|
||||
#include "surface.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm> // Para min, max, copy_n, fill
|
||||
@@ -177,32 +178,32 @@ void Surface::putPixel(int x, int y, Uint8 color) {
|
||||
}
|
||||
|
||||
// Obtiene el color de un pixel de la surface_data
|
||||
Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * surface_data_->width]; }
|
||||
Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * static_cast<int>(surface_data_->width)]; }
|
||||
|
||||
// Dibuja un rectangulo relleno
|
||||
void Surface::fillRect(const SDL_Rect* rect, Uint8 color) {
|
||||
void Surface::fillRect(const SDL_FRect* rect, Uint8 color) {
|
||||
// Limitar los valores del rectángulo al tamaño de la superficie
|
||||
int x_start = std::max(0, rect->x);
|
||||
int y_start = std::max(0, rect->y);
|
||||
int x_end = std::min(rect->x + rect->w, static_cast<int>(surface_data_->width));
|
||||
int y_end = std::min(rect->y + rect->h, static_cast<int>(surface_data_->height));
|
||||
float x_start = std::max(0.0F, rect->x);
|
||||
float y_start = std::max(0.0F, rect->y);
|
||||
float x_end = std::min(rect->x + rect->w, surface_data_->width);
|
||||
float y_end = std::min(rect->y + rect->h, surface_data_->height);
|
||||
|
||||
// Recorrer cada píxel dentro del rectángulo directamente
|
||||
for (int y = y_start; y < y_end; ++y) {
|
||||
for (int x = x_start; x < x_end; ++x) {
|
||||
const int index = x + y * surface_data_->width;
|
||||
surface_data_->data.get()[index] = color;
|
||||
const int INDEX = x + y * surface_data_->width;
|
||||
surface_data_->data.get()[INDEX] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el borde de un rectangulo
|
||||
void Surface::drawRectBorder(const SDL_Rect* rect, Uint8 color) {
|
||||
void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) {
|
||||
// Limitar los valores del rectángulo al tamaño de la superficie
|
||||
int x_start = std::max(0, rect->x);
|
||||
int y_start = std::max(0, rect->y);
|
||||
int x_end = std::min(rect->x + rect->w, static_cast<int>(surface_data_->width));
|
||||
int y_end = std::min(rect->y + rect->h, static_cast<int>(surface_data_->height));
|
||||
float x_start = std::max(0.0F, rect->x);
|
||||
float y_start = std::max(0.0F, rect->y);
|
||||
float x_end = std::min(rect->x + rect->w, surface_data_->width);
|
||||
float y_end = std::min(rect->y + rect->h, surface_data_->height);
|
||||
|
||||
// Dibujar bordes horizontales
|
||||
for (int x = x_start; x < x_end; ++x) {
|
||||
@@ -218,31 +219,31 @@ void Surface::drawRectBorder(const SDL_Rect* rect, Uint8 color) {
|
||||
// Dibujar bordes verticales
|
||||
for (int y = y_start; y < y_end; ++y) {
|
||||
// Borde izquierdo
|
||||
const int left_index = x_start + y * surface_data_->width;
|
||||
surface_data_->data.get()[left_index] = color;
|
||||
const int LEFT_INDEX = x_start + y * surface_data_->width;
|
||||
surface_data_->data.get()[LEFT_INDEX] = color;
|
||||
|
||||
// Borde derecho
|
||||
const int right_index = (x_end - 1) + y * surface_data_->width;
|
||||
surface_data_->data.get()[right_index] = color;
|
||||
const int RIGHT_INDEX = (x_end - 1) + y * surface_data_->width;
|
||||
surface_data_->data.get()[RIGHT_INDEX] = color;
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja una linea
|
||||
void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color) {
|
||||
void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) {
|
||||
// Calcula las diferencias
|
||||
int dx = std::abs(x2 - x1);
|
||||
int dy = std::abs(y2 - y1);
|
||||
float dx = std::abs(x2 - x1);
|
||||
float dy = std::abs(y2 - y1);
|
||||
|
||||
// Determina la dirección del incremento
|
||||
int sx = (x1 < x2) ? 1 : -1;
|
||||
int sy = (y1 < y2) ? 1 : -1;
|
||||
float sx = (x1 < x2) ? 1 : -1;
|
||||
float sy = (y1 < y2) ? 1 : -1;
|
||||
|
||||
int err = dx - dy;
|
||||
float err = dx - dy;
|
||||
|
||||
while (true) {
|
||||
// Asegúrate de no dibujar fuera de los límites de la superficie
|
||||
if (x1 >= 0 && x1 < surface_data_->width && y1 >= 0 && y1 < surface_data_->height) {
|
||||
surface_data_->data.get()[x1 + y1 * surface_data_->width] = color;
|
||||
surface_data_->data.get()[static_cast<size_t>(x1 + y1 * surface_data_->width)] = color;
|
||||
}
|
||||
|
||||
// Si alcanzamos el punto final, salimos
|
||||
@@ -261,7 +262,7 @@ void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color) {
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::render(int dx, int dy, int sx, int sy, int w, int h) {
|
||||
void Surface::render(float dx, float dy, float sx, float sy, float w, float h) {
|
||||
auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData();
|
||||
|
||||
// Limitar la región para evitar accesos fuera de rango en origen
|
||||
@@ -280,9 +281,9 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) {
|
||||
int src_x = sx + ix;
|
||||
int src_y = sy + iy;
|
||||
|
||||
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
|
||||
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
|
||||
if (color != transparent_color_) {
|
||||
surface_data->data.get()[dest_x + dest_y * surface_data->width] = sub_palette_[color];
|
||||
surface_data->data.get()[static_cast<size_t>(dest_x + dest_y * surface_data->width)] = sub_palette_[color];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,14 +291,14 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) {
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) {
|
||||
void Surface::render(int x, int y, SDL_FRect* srcRect, SDL_FlipMode flip) {
|
||||
auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData();
|
||||
|
||||
// Determina la región de origen (clip) a renderizar
|
||||
int sx = (srcRect) ? srcRect->x : 0;
|
||||
int sy = (srcRect) ? srcRect->y : 0;
|
||||
int w = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
int h = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
float sx = (srcRect) ? srcRect->x : 0;
|
||||
float sy = (srcRect) ? srcRect->y : 0;
|
||||
float w = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
float h = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
|
||||
// Limitar la región para evitar accesos fuera de rango en origen
|
||||
w = std::min(w, surface_data_->width - sx);
|
||||
@@ -323,7 +324,7 @@ void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) {
|
||||
// Verificar que las coordenadas de destino están dentro de los límites
|
||||
if (dest_x >= 0 && dest_x < surface_data_dest->width && dest_y >= 0 && dest_y < surface_data_dest->height) {
|
||||
// Copia el píxel si no es transparente
|
||||
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
|
||||
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
|
||||
if (color != transparent_color_) {
|
||||
surface_data_dest->data[dest_x + dest_y * surface_data_dest->width] = sub_palette_[color];
|
||||
}
|
||||
@@ -333,20 +334,20 @@ void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) {
|
||||
}
|
||||
|
||||
// Copia una región de la superficie de origen a la de destino
|
||||
void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip) {
|
||||
void Surface::render(SDL_FRect* srcRect, SDL_FRect* dstRect, SDL_FlipMode flip) {
|
||||
auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData();
|
||||
|
||||
// Si srcRect es nullptr, tomar toda la superficie fuente
|
||||
int sx = (srcRect) ? srcRect->x : 0;
|
||||
int sy = (srcRect) ? srcRect->y : 0;
|
||||
int sw = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
int sh = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
float sx = (srcRect) ? srcRect->x : 0;
|
||||
float sy = (srcRect) ? srcRect->y : 0;
|
||||
float sw = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
float sh = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
|
||||
// Si dstRect es nullptr, asignar las mismas dimensiones que srcRect
|
||||
int dx = (dstRect) ? dstRect->x : 0;
|
||||
int dy = (dstRect) ? dstRect->y : 0;
|
||||
int dw = (dstRect) ? dstRect->w : sw;
|
||||
int dh = (dstRect) ? dstRect->h : sh;
|
||||
float dx = (dstRect) ? dstRect->x : 0;
|
||||
float dy = (dstRect) ? dstRect->y : 0;
|
||||
float dw = (dstRect) ? dstRect->w : sw;
|
||||
float dh = (dstRect) ? dstRect->h : sh;
|
||||
|
||||
// Asegurarse de que srcRect y dstRect tienen las mismas dimensiones
|
||||
if (sw != dw || sh != dh) {
|
||||
@@ -374,7 +375,7 @@ void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip
|
||||
if (int dest_x = dx + ix; dest_x >= 0 && dest_x < surface_data->width) {
|
||||
if (int dest_y = dy + iy; dest_y >= 0 && dest_y < surface_data->height) {
|
||||
// Copiar el píxel si no es transparente
|
||||
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
|
||||
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
|
||||
if (color != transparent_color_) {
|
||||
surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color];
|
||||
}
|
||||
@@ -385,14 +386,14 @@ void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip
|
||||
}
|
||||
|
||||
// Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro
|
||||
void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_Rect* srcRect, SDL_RendererFlip flip) {
|
||||
void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_FRect* srcRect, SDL_FlipMode flip) {
|
||||
auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData();
|
||||
|
||||
// Determina la región de origen (clip) a renderizar
|
||||
int sx = (srcRect) ? srcRect->x : 0;
|
||||
int sy = (srcRect) ? srcRect->y : 0;
|
||||
int w = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
int h = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
float sx = (srcRect) ? srcRect->x : 0;
|
||||
float sy = (srcRect) ? srcRect->y : 0;
|
||||
float w = (srcRect) ? srcRect->w : surface_data_->width;
|
||||
float h = (srcRect) ? srcRect->h : surface_data_->height;
|
||||
|
||||
// Limitar la región para evitar accesos fuera de rango
|
||||
w = std::min(w, surface_data_->width - sx);
|
||||
@@ -415,7 +416,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
|
||||
}
|
||||
|
||||
// Copia el píxel si no es transparente
|
||||
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
|
||||
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
|
||||
if (color != transparent_color_) {
|
||||
surface_data->data[dest_x + dest_y * surface_data->width] =
|
||||
(color == source_color) ? target_color : color;
|
||||
@@ -458,13 +459,13 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) {
|
||||
SDL_UnlockTexture(texture); // Desbloquea la textura
|
||||
|
||||
// Renderiza la textura en la pantalla completa
|
||||
if (SDL_RenderCopy(renderer, texture, nullptr, nullptr) != 0) {
|
||||
if (SDL_RenderTexture(renderer, texture, nullptr, nullptr) != 0) {
|
||||
throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
// Vuelca la superficie a una textura
|
||||
void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect* srcRect, SDL_Rect* destRect) {
|
||||
void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* srcRect, SDL_FRect* destRect) {
|
||||
if (!renderer || !texture || !surface_data_) {
|
||||
throw std::runtime_error("Renderer or texture is null.");
|
||||
}
|
||||
@@ -476,7 +477,16 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Re
|
||||
Uint32* pixels = nullptr;
|
||||
int pitch = 0;
|
||||
|
||||
if (SDL_LockTexture(texture, destRect, reinterpret_cast<void**>(&pixels), &pitch) != 0) {
|
||||
SDL_Rect lockRect;
|
||||
if (destRect) {
|
||||
lockRect.x = static_cast<int>(destRect->x);
|
||||
lockRect.y = static_cast<int>(destRect->y);
|
||||
lockRect.w = static_cast<int>(destRect->w);
|
||||
lockRect.h = static_cast<int>(destRect->h);
|
||||
}
|
||||
|
||||
// Usa lockRect solo si destRect no es nulo
|
||||
if (SDL_LockTexture(texture, destRect ? &lockRect : nullptr, reinterpret_cast<void**>(&pixels), &pitch) != 0) {
|
||||
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
|
||||
}
|
||||
|
||||
@@ -494,7 +504,7 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Re
|
||||
SDL_UnlockTexture(texture);
|
||||
|
||||
// Renderiza la textura con los rectángulos especificados
|
||||
if (SDL_RenderCopy(renderer, texture, srcRect, destRect) != 0) {
|
||||
if (SDL_RenderTexture(renderer, texture, srcRect, destRect) != 0) {
|
||||
throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ Palette readPalFile(const std::string& file_path);
|
||||
|
||||
struct SurfaceData {
|
||||
std::shared_ptr<Uint8[]> data; // Usa std::shared_ptr para gestión automática
|
||||
Uint16 width; // Ancho de la imagen
|
||||
Uint16 height; // Alto de la imagen
|
||||
float width; // Ancho de la imagen
|
||||
float height; // Alto de la imagen
|
||||
|
||||
// Constructor por defecto
|
||||
SurfaceData()
|
||||
@@ -32,13 +32,13 @@ struct SurfaceData {
|
||||
height(0) {}
|
||||
|
||||
// Constructor que inicializa dimensiones y asigna memoria
|
||||
SurfaceData(Uint16 w, Uint16 h)
|
||||
: data(std::shared_ptr<Uint8[]>(new Uint8[w * h](), std::default_delete<Uint8[]>())),
|
||||
SurfaceData(float w, float h)
|
||||
: data(std::shared_ptr<Uint8[]>(new Uint8[static_cast<size_t>(w * h)](), std::default_delete<Uint8[]>())),
|
||||
width(w),
|
||||
height(h) {}
|
||||
|
||||
// Constructor para inicializar directamente con datos
|
||||
SurfaceData(Uint16 w, Uint16 h, std::shared_ptr<Uint8[]> pixels)
|
||||
SurfaceData(float w, float h, std::shared_ptr<Uint8[]> pixels)
|
||||
: data(std::move(pixels)),
|
||||
width(w),
|
||||
height(h) {}
|
||||
@@ -77,12 +77,12 @@ class Surface {
|
||||
void loadPalette(Palette palette);
|
||||
|
||||
// Copia una región de la SurfaceData de origen a la SurfaceData de destino
|
||||
void render(int dx, int dy, int sx, int sy, int w, int h);
|
||||
void render(int x, int y, SDL_Rect* clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
||||
void render(SDL_Rect* srcRect = nullptr, SDL_Rect* dstRect = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
||||
void render(float dx, float dy, float sx, float sy, float w, float h);
|
||||
void render(int x, int y, SDL_FRect* clip = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE);
|
||||
void render(SDL_FRect* srcRect = nullptr, SDL_FRect* dstRect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE);
|
||||
|
||||
// Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro
|
||||
void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect* srcRect = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
||||
void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_FRect* srcRect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE);
|
||||
|
||||
// Establece un color en la paleta
|
||||
void setColor(int index, Uint32 color);
|
||||
@@ -92,7 +92,7 @@ class Surface {
|
||||
|
||||
// Vuelca la SurfaceData a una textura
|
||||
void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture);
|
||||
void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect* srcRect, SDL_Rect* destRect);
|
||||
void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* srcRect, SDL_FRect* destRect);
|
||||
|
||||
// Realiza un efecto de fundido en las paletas
|
||||
bool fadePalette();
|
||||
@@ -105,21 +105,21 @@ class Surface {
|
||||
Uint8 getPixel(int x, int y);
|
||||
|
||||
// Dibuja un rectangulo relleno
|
||||
void fillRect(const SDL_Rect* rect, Uint8 color);
|
||||
void fillRect(const SDL_FRect* rect, Uint8 color);
|
||||
|
||||
// Dibuja el borde de un rectangulo
|
||||
void drawRectBorder(const SDL_Rect* rect, Uint8 color);
|
||||
void drawRectBorder(const SDL_FRect* rect, Uint8 color);
|
||||
|
||||
// Dibuja una linea
|
||||
void drawLine(int x1, int y1, int x2, int y2, Uint8 color);
|
||||
void drawLine(float x1, float y1, float x2, float y2, Uint8 color);
|
||||
|
||||
// Metodos para gestionar surface_data_
|
||||
std::shared_ptr<SurfaceData> getSurfaceData() const { return surface_data_; }
|
||||
void setSurfaceData(std::shared_ptr<SurfaceData> new_data) { surface_data_ = new_data; }
|
||||
|
||||
// Obtien ancho y alto
|
||||
int getWidth() const { return surface_data_->width; }
|
||||
int getHeight() const { return surface_data_->height; }
|
||||
float getWidth() const { return surface_data_->width; }
|
||||
float getHeight() const { return surface_data_->height; }
|
||||
|
||||
// Color transparente
|
||||
Uint8 getTransparentColor() const { return transparent_color_; }
|
||||
|
||||
@@ -88,7 +88,7 @@ Text::Text(std::shared_ptr<Surface> surface, const std::string& text_file) {
|
||||
}
|
||||
|
||||
// Crea los objetos
|
||||
sprite_ = std::make_unique<SSprite>(surface, (SDL_Rect){0, 0, box_width_, box_height_});
|
||||
sprite_ = std::make_unique<SSprite>(surface, (SDL_FRect){0, 0, box_width_, box_height_});
|
||||
|
||||
// Inicializa variables
|
||||
fixed_width_ = false;
|
||||
@@ -106,7 +106,7 @@ Text::Text(std::shared_ptr<Surface> surface, std::shared_ptr<TextFile> text_file
|
||||
}
|
||||
|
||||
// Crea los objetos
|
||||
sprite_ = std::make_unique<SSprite>(surface, (SDL_Rect){0, 0, box_width_, box_height_});
|
||||
sprite_ = std::make_unique<SSprite>(surface, (SDL_FRect){0, 0, box_width_, box_height_});
|
||||
|
||||
// Inicializa variables
|
||||
fixed_width_ = false;
|
||||
|
||||
@@ -194,7 +194,7 @@ void Notifier::show(std::vector<std::string> texts, NotificationText text_is, Ui
|
||||
Screen::get()->setRendererSurface(n.surface);
|
||||
|
||||
// Dibuja el fondo de la notificación
|
||||
SDL_Rect rect;
|
||||
SDL_FRect rect;
|
||||
if (SHAPE == NotificationShape::ROUNDED) {
|
||||
rect = {4, 0, WIDTH - (4 * 2), HEIGHT};
|
||||
n.surface->fillRect(&rect, bg_color_);
|
||||
@@ -211,13 +211,13 @@ void Notifier::show(std::vector<std::string> texts, NotificationText text_is, Ui
|
||||
|
||||
else if (SHAPE == NotificationShape::SQUARED) {
|
||||
n.surface->clear(bg_color_);
|
||||
SDL_Rect squared_rect = {0, 0, n.surface->getWidth(), n.surface->getHeight()};
|
||||
SDL_FRect squared_rect = {0, 0, n.surface->getWidth(), n.surface->getHeight()};
|
||||
n.surface->drawRectBorder(&squared_rect, static_cast<Uint8>(PaletteColor::CYAN));
|
||||
}
|
||||
|
||||
// Dibuja el icono de la notificación
|
||||
if (has_icons_ && icon >= 0 && texts.size() >= 2) {
|
||||
auto sp = std::make_unique<SSprite>(icon_surface_, (SDL_Rect){0, 0, ICON_SIZE_, ICON_SIZE_});
|
||||
auto sp = std::make_unique<SSprite>(icon_surface_, (SDL_FRect){0, 0, ICON_SIZE_, ICON_SIZE_});
|
||||
sp->setPosition({PADDING_IN_H, PADDING_IN_V, ICON_SIZE_, ICON_SIZE_});
|
||||
sp->setClip({ICON_SIZE_ * (icon % 10), ICON_SIZE_ * (icon / 10), ICON_SIZE_, ICON_SIZE_});
|
||||
sp->render();
|
||||
|
||||
@@ -46,7 +46,7 @@ class Notifier {
|
||||
std::vector<std::string> texts; // Lista de textos incluidos en la notificación
|
||||
NotificationStatus state; // Estado actual de la notificación (RISING, SHOWING, etc.)
|
||||
NotificationShape shape; // Forma de la notificación (ej. SQUARED o ROUNDED)
|
||||
SDL_Rect rect; // Dimensiones y posición de la notificación en pantalla
|
||||
SDL_FRect rect; // Dimensiones y posición de la notificación en pantalla
|
||||
int y; // Posición actual en el eje Y
|
||||
int travel_dist; // Distancia a recorrer (por ejemplo, en animaciones)
|
||||
std::string code; // Código identificador único para esta notificación
|
||||
|
||||
@@ -39,7 +39,7 @@ bool checkCollision(const Circle& a, const Circle& b) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre un circulo y un rectangulo
|
||||
bool checkCollision(const Circle& a, const SDL_Rect& b) {
|
||||
bool checkCollision(const Circle& a, const SDL_FRect& b) {
|
||||
// Closest point on collision box
|
||||
int cX, cY;
|
||||
|
||||
@@ -72,7 +72,7 @@ bool checkCollision(const Circle& a, const SDL_Rect& b) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre dos rectangulos
|
||||
bool checkCollision(const SDL_Rect& a, const SDL_Rect& b) {
|
||||
bool checkCollision(const SDL_FRect& a, const SDL_FRect& b) {
|
||||
// Calcula las caras del rectangulo a
|
||||
const int leftA = a.x;
|
||||
const int rightA = a.x + a.w;
|
||||
@@ -107,7 +107,7 @@ bool checkCollision(const SDL_Rect& a, const SDL_Rect& b) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre un punto y un rectangulo
|
||||
bool checkCollision(const SDL_Point& p, const SDL_Rect& r) {
|
||||
bool checkCollision(const SDL_FPoint& p, const SDL_FRect& r) {
|
||||
// Comprueba si el punto está a la izquierda del rectangulo
|
||||
if (p.x < r.x) {
|
||||
return false;
|
||||
@@ -133,7 +133,7 @@ bool checkCollision(const SDL_Point& p, const SDL_Rect& r) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre una linea horizontal y un rectangulo
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_Rect& r) {
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_FRect& r) {
|
||||
// Comprueba si la linea esta por encima del rectangulo
|
||||
if (l.y < r.y) {
|
||||
return false;
|
||||
@@ -159,7 +159,7 @@ bool checkCollision(const LineHorizontal& l, const SDL_Rect& r) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre una linea vertical y un rectangulo
|
||||
bool checkCollision(const LineVertical& l, const SDL_Rect& r) {
|
||||
bool checkCollision(const LineVertical& l, const SDL_FRect& r) {
|
||||
// Comprueba si la linea esta por la izquierda del rectangulo
|
||||
if (l.x < r.x) {
|
||||
return false;
|
||||
@@ -185,7 +185,7 @@ bool checkCollision(const LineVertical& l, const SDL_Rect& r) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre una linea horizontal y un punto
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_Point& p) {
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_FPoint& p) {
|
||||
// Comprueba si el punto esta sobre la linea
|
||||
if (p.y > l.y) {
|
||||
return false;
|
||||
@@ -211,7 +211,7 @@ bool checkCollision(const LineHorizontal& l, const SDL_Point& p) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre dos lineas
|
||||
SDL_Point checkCollision(const Line& l1, const Line& l2) {
|
||||
SDL_FPoint checkCollision(const Line& l1, const Line& l2) {
|
||||
const float x1 = l1.x1;
|
||||
const float y1 = l1.y1;
|
||||
const float x2 = l1.x2;
|
||||
@@ -238,7 +238,7 @@ SDL_Point checkCollision(const Line& l1, const Line& l2) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre dos lineas
|
||||
SDL_Point checkCollision(const LineDiagonal& l1, const LineVertical& l2) {
|
||||
SDL_FPoint checkCollision(const LineDiagonal& l1, const LineVertical& l2) {
|
||||
const float x1 = l1.x1;
|
||||
const float y1 = l1.y1;
|
||||
const float x2 = l1.x2;
|
||||
@@ -279,7 +279,7 @@ void normalizeLine(LineDiagonal& l) {
|
||||
}
|
||||
|
||||
// Detector de colisiones entre un punto y una linea diagonal
|
||||
bool checkCollision(const SDL_Point& p, const LineDiagonal& l) {
|
||||
bool checkCollision(const SDL_FPoint& p, const LineDiagonal& l) {
|
||||
// Comprueba si el punto está en alineado con la linea
|
||||
if (abs(p.x - l.x1) != abs(p.y - l.y1)) {
|
||||
return false;
|
||||
|
||||
@@ -42,22 +42,22 @@ struct Circle {
|
||||
|
||||
// Estructura para definir una linea horizontal
|
||||
struct LineHorizontal {
|
||||
int x1, x2, y;
|
||||
float x1, x2, y;
|
||||
};
|
||||
|
||||
// Estructura para definir una linea vertical
|
||||
struct LineVertical {
|
||||
int x, y1, y2;
|
||||
float x, y1, y2;
|
||||
};
|
||||
|
||||
// Estructura para definir una linea diagonal
|
||||
struct LineDiagonal {
|
||||
int x1, y1, x2, y2;
|
||||
float x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
// Estructura para definir una linea
|
||||
struct Line {
|
||||
int x1, y1, x2, y2;
|
||||
float x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
// Estructura para definir un color
|
||||
@@ -86,31 +86,31 @@ double distanceSquared(int x1, int y1, int x2, int y2);
|
||||
bool checkCollision(const Circle& a, const Circle& b);
|
||||
|
||||
// Detector de colisiones entre un circulo y un rectangulo
|
||||
bool checkCollision(const Circle& a, const SDL_Rect& b);
|
||||
bool checkCollision(const Circle& a, const SDL_FRect& b);
|
||||
|
||||
// Detector de colisiones entre un dos rectangulos
|
||||
bool checkCollision(const SDL_Rect& a, const SDL_Rect& b);
|
||||
bool checkCollision(const SDL_FRect& a, const SDL_FRect& b);
|
||||
|
||||
// Detector de colisiones entre un punto y un rectangulo
|
||||
bool checkCollision(const SDL_Point& p, const SDL_Rect& r);
|
||||
bool checkCollision(const SDL_FPoint& p, const SDL_FRect& r);
|
||||
|
||||
// Detector de colisiones entre una linea horizontal y un rectangulo
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_Rect& r);
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_FRect& r);
|
||||
|
||||
// Detector de colisiones entre una linea vertical y un rectangulo
|
||||
bool checkCollision(const LineVertical& l, const SDL_Rect& r);
|
||||
bool checkCollision(const LineVertical& l, const SDL_FRect& r);
|
||||
|
||||
// Detector de colisiones entre una linea horizontal y un punto
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_Point& p);
|
||||
bool checkCollision(const LineHorizontal& l, const SDL_FPoint& p);
|
||||
|
||||
// Detector de colisiones entre dos lineas
|
||||
SDL_Point checkCollision(const Line& l1, const Line& l2);
|
||||
SDL_FPoint checkCollision(const Line& l1, const Line& l2);
|
||||
|
||||
// Detector de colisiones entre dos lineas
|
||||
SDL_Point checkCollision(const LineDiagonal& l1, const LineVertical& l2);
|
||||
SDL_FPoint checkCollision(const LineDiagonal& l1, const LineVertical& l2);
|
||||
|
||||
// Detector de colisiones entre un punto y una linea diagonal
|
||||
bool checkCollision(const SDL_Point& p, const LineDiagonal& l);
|
||||
bool checkCollision(const SDL_FPoint& p, const LineDiagonal& l);
|
||||
|
||||
// Normaliza una linea diagonal
|
||||
void normalizeLine(LineDiagonal& l);
|
||||
|
||||
Reference in New Issue
Block a user