first commit

This commit is contained in:
2021-02-21 11:04:22 +01:00
commit ca2dff3d81
34 changed files with 16737 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
.vscode/*
.DS_Store
thumbs.db
*debug*
*.psd
*.zip
*.aseprite
media_work
resources
source/old
bin

6
Makefile Normal file
View File

@@ -0,0 +1,6 @@
macos:
mkdir -p bin
g++ source/*.cpp -std=c++11 -Wall -O2 -lSDL2 -lSDL2_image -lSDL2_mixer -o bin/volcano_macos
linux:
mkdir -p bin
g++ source/*.cpp -std=c++11 -Wall -O2 -lSDL2 -lSDL2_image -lSDL2_mixer -o bin/volcano_macos

BIN
data/volcano.map Normal file

Binary file not shown.

BIN
data/volcano.map.bak1 Normal file

Binary file not shown.

BIN
data/volcano.map.bak2 Normal file

Binary file not shown.

BIN
media/gfx/actors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
media/gfx/bkg_surface.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
media/gfx/filter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
media/gfx/hud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
media/gfx/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 KiB

BIN
media/gfx/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
media/gfx/tiles_surface.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
media/gfx/tiles_volcano.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
media/music/music_menu.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

View File

View File

View File

View File

View File

374
source/const.h Normal file
View File

@@ -0,0 +1,374 @@
#pragma once
#include "ifdefs.h"
#include <string>
#ifndef CONST_H
#define CONST_H
// Textos
const std::string WINDOW_TITLE = "Volcano v0005";
const std::string BUILD = ".05";
const std::string FILE_MAP_VOLCANO = "../data/volcano.map.bak1";
const std::string FILE_TILES_VOLCANO = "../media/gfx/tiles_volcano.png";
const std::string FILE_TILES_SURFACE = "../media/gfx/tiles_surface.png";
const std::string FILE_BKG_SURFACE = "../media/gfx/bkg_surface.png";
const std::string FILE_MENU = "../media/gfx/menu.png";
const std::string FILE_MENU_ANIMATION = "../media/gfx/menu_animation.png";
const std::string FILE_ACTORS = "../media/gfx/actors.png";
const std::string FILE_PLAYER = "../media/gfx/player.png";
const std::string FILE_HUD = "../media/gfx/hud.png";
const std::string FILE_FILTER = "../media/gfx/filter.png";
const std::string FILE_SOUND_JUMP = "../media/sound/sound_player_jump.wav";
const std::string FILE_SOUND_DEATH = "../media/sound/sound_player_death.wav";
const std::string FILE_SOUND_COIN = "../media/sound/sound_player_coin.wav";
const std::string FILE_SOUND_MENU_LOGO = "../media/sound/sound_menu_logo.wav";
const std::string FILE_SOUND_MENU_START = "../media/sound/sound_menu_start.wav";
const std::string FILE_SOUND_DROP_ENEMY = "../media/sound/sound_drop_enemy.wav";
const std::string FILE_SOUND_DROP_SPLAT = "../media/sound/sound_drop_splat.wav";
const std::string FILE_MUSIC_SURFACE = "../media/music/music_surface.ogg";
const std::string FILE_MUSIC_VOLCANO = "../media/music/music_volcano.ogg";
const std::string FILE_MUSIC_MENU = "../media/music/music_menu.ogg";
const Uint8 GAME_SPEED = 24; //16 = normal-rapido, 24 = normal. Cuanto mas pequeño, más rápido
const Uint8 UP = 0;
const Uint8 DOWN = 2;
const Uint8 RIGHT = 1;
const Uint8 LEFT = 3;
const Uint8 NONE = 4;
const Uint8 MAP_TILE_HEIGHT = 16;
const Uint8 MAP_TILE_WIDTH = 16;
const Uint8 ROOM_WIDTH_IN_TILES = 20;
const Uint8 ROOM_HEIGHT_IN_TILES = 14;
const Uint16 GAME_WINDOW_WIDTH = 320;
const Uint16 GAME_WINDOW_HEIGHT = 234;
const Uint8 TEST_ROOM = 118; // 161
const Uint8 STARTING_ROOM = 2;
const Uint8 STARTING_PLAYER_TILE_X = 5;
const Uint8 STARTING_PLAYER_TILE_Y = 11;
const Uint8 ENEMY_HITBOX_REDUCTION = 4;
const Uint8 COOLDOWN_TIME = 50;
const Uint8 GRAVITY = 0;
const Uint8 MAX_SPEED_Y = 5;
const Uint8 BASE_SPEED = 1;
const Uint8 MAX_SPEED = 8;
const Uint8 RATIO_SPEED = 8;
const Uint8 DROP_TIMER = 100;
const Uint8 TOP_COLLISION = 0;
const Uint8 BOTTOM_COLLISION = 1;
const Uint8 LEFT_COLLISION = 2;
const Uint8 RIGHT_COLLISION = 3;
const Uint8 NO_COLLISION = 4;
const Uint8 MAX_ACTORS = 50;
const Uint8 KIND_FLYING_ENEMY = 0;
const Uint8 KIND_COIN = 1;
const Uint8 KIND_HEART = 2;
const Uint8 KIND_STATIC_ENEMY = 3;
const Uint8 KIND_MOBILE_PLATFORM = 4;
const Uint8 KIND_WALKING_ENEMY = 5;
const Uint8 KIND_DROP_GENERATOR = 6;
const Uint8 KIND_DROP_ENEMY = 7;
const Uint8 KIND_DROP_SPLAT = 8;
const Uint8 KIND_SPEED_ENEMY = 9;
const Uint8 KIND_KEY = 10;
const Uint8 KIND_LOCK = 11;
const Uint8 CODE_ENEMY_V1U = 208;
const Uint8 CODE_ENEMY_V2U = 209;
const Uint8 CODE_ENEMY_V3U = 210;
const Uint8 CODE_ENEMY_V1D = 211;
const Uint8 CODE_ENEMY_V2D = 212;
const Uint8 CODE_ENEMY_V3D = 213;
const Uint8 CODE_ENEMY_H1L = 214;
const Uint8 CODE_ENEMY_H2L = 215;
const Uint8 CODE_ENEMY_H3L = 216;
const Uint8 CODE_ENEMY_H1R = 217;
const Uint8 CODE_ENEMY_H2R = 218;
const Uint8 CODE_ENEMY_H3R = 219;
const Uint8 CODE_ENEMY_W1L = 224;
const Uint8 CODE_ENEMY_W2L = 225;
const Uint8 CODE_ENEMY_W3L = 226;
const Uint8 CODE_ENEMY_W1R = 227;
const Uint8 CODE_ENEMY_W2R = 228;
const Uint8 CODE_ENEMY_W3R = 229;
const Uint8 CODE_ENEMY_DRP = 230;
const Uint8 CODE_ENEMY_SPL = 231;
const Uint8 CODE_ENEMY_SPR = 232;
const Uint8 CODE_COIN = 240;
const Uint8 CODE_HEART = 241;
const Uint8 CODE_KEY_RED = 242;
const Uint8 CODE_LOCK_RED = 243;
const Uint8 CODE_KEY_BLUE = 244;
const Uint8 CODE_LOCK_BLUE = 245;
const Uint8 CODE_KEY_GREEN = 246;
const Uint8 CODE_LOCK_GREEN = 247;
const Uint8 CODE_KEY_YELLOW = 248;
const Uint8 CODE_LOCK_YELLOW = 249;
const Uint8 MAX_ANIMATED_TILES = 200;
const Uint8 TILE_BACKGROUND = 0;
const Uint8 TILE_PLATFORM = 1;
const Uint8 TILE_KILLING_PLATFORM = 2;
const Uint8 TILE_ACTOR = 3;
const Uint8 TILE_TRAVESABLE_PLATFORM = 4;
const Uint8 PLAYER_ANIMATION_STANDING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_STANDING_RIGHT = 1;
const Uint8 PLAYER_ANIMATION_WALKING_LEFT = 2;
const Uint8 PLAYER_ANIMATION_WALKING_RIGHT = 3;
const Uint8 PLAYER_ANIMATION_JUMPING_LEFT = 4;
const Uint8 PLAYER_ANIMATION_JUMPING_RIGHT = 5;
const Uint8 PLAYER_ANIMATION_DYING_LEFT = 6;
const Uint8 PLAYER_ANIMATION_DYING_RIGHT = 7;
const Uint8 SECTION_MENU = 0;
const Uint8 SECTION_GAME = 1;
const Uint8 SECTION_QUIT = 2;
const Uint8 MENU_SECTION_MAIN = 0;
const Uint8 MENU_SECTION_CREDITS = 1;
const Uint8 MENU_SECTION_ANIMATION = 2;
const Uint8 ZONE_SURFACE = 0;
const Uint8 ZONE_VOLCANO = 1;
// Recursos
///////////////////////////////COFFEE CRISIS//////////////////////////////////////////////
// Tamaño de bloque
const Uint8 BLOCK = 8;
const Uint8 HALF_BLOCK = BLOCK / 2;
// Tamaño de la pantalla real
const int SCREEN_WIDTH = 320;
const int SCREEN_HEIGHT = SCREEN_WIDTH * 3 / 4; // 240
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3; // 960
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3; // 720
// Cantidad de enteros a escribir en los ficheros de datos
const Uint8 TOTAL_SCORE_DATA = 3;
const Uint16 TOTAL_DEMO_DATA = 2000;
// Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = SCREEN_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = SCREEN_WIDTH - (0 * BLOCK);
const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT;
const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP;
const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2);
const int PLAY_AREA_CENTER_Y = PLAY_AREA_TOP + (PLAY_AREA_HEIGHT / 2);
const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
// Anclajes de pantalla
const int SCREEN_CENTER_X = SCREEN_WIDTH / 2;
const int SCREEN_FIRST_QUARTER_X = SCREEN_WIDTH / 4;
const int SCREEN_THIRD_QUARTER_X = (SCREEN_WIDTH / 4) * 3;
const int SCREEN_CENTER_Y = SCREEN_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
// Color transparente para los sprites
const Uint8 COLOR_KEY_R = 0xff;
const Uint8 COLOR_KEY_G = 0x00;
const Uint8 COLOR_KEY_B = 0xff;
// Opciones de menu
const int MENU_NO_OPTION = -1;
const int MENU_OPTION_START = 0;
const int MENU_OPTION_QUIT = 1;
const int MENU_OPTION_TOTAL = 2;
// Selector de menu
const int MENU_SELECTOR_BLACK = (BLOCK * 0);
const int MENU_SELECTOR_WHITE = (BLOCK * 1);
// Tipos de fondos para el menu
const int MENU_BACKGROUND_TRANSPARENT = 0;
const int MENU_BACKGROUND_SOLID = 1;
// Estados del jugador
const Uint8 PLAYER_STATUS_WALKING_LEFT = 0;
const Uint8 PLAYER_STATUS_WALKING_RIGHT = 1;
const Uint8 PLAYER_STATUS_WALKING_STOP = 2;
const Uint8 PLAYER_STATUS_FIRING_UP = 0;
const Uint8 PLAYER_STATUS_FIRING_LEFT = 1;
const Uint8 PLAYER_STATUS_FIRING_RIGHT = 2;
const Uint8 PLAYER_STATUS_FIRING_NO = 3;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_RIGHT = 1;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_STOP = 2;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_LEFT = 1;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_RIGHT = 2;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_RIGHT = 3;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_STOP = 4;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_UP = 5;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_LEFT_EXTRA_HIT = 6;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_LEFT_EXTRA_HIT = 7;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_RIGHT_EXTRA_HIT = 8;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_RIGHT_EXTRA_HIT = 9;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_STOP_EXTRA_HIT = 10;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_UP_EXTRA_HIT = 11;
// Variables del jugador
const Uint16 PLAYER_INVULNERABLE_TIMER = 200;
// Estados del juego
const Uint8 GAME_SECTION_TITLE = 0;
const Uint8 GAME_SECTION_PLAYING = 1;
const Uint8 GAME_SECTION_QUIT = 2;
const Uint8 GAME_SECTION_GAME_OVER_SCREEN = 3;
const Uint8 GAME_SECTION_INTRO = 4;
const Uint8 GAME_SECTION_DEMO = 5;
const Uint8 GAME_SECTION_INSTRUCTIONS = 6;
const Uint8 GAME_SECTION_LOGO = 7;
const Uint8 GAME_SECTION_INIT = 8;
// Estados de cada elemento que pertenece a un evento
const Uint8 EVENT_WAITING = 1;
const Uint8 EVENT_RUNNING = 2;
const Uint8 EVENT_COMPLETED = 3;
// Cantidad de eventos de la intro
const Uint8 INTRO_TOTAL_BITMAPS = 6;
const Uint8 INTRO_TOTAL_TEXTS = 9;
const Uint8 INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Cantidad de eventos de la pantalla de titulo
const Uint8 TITLE_TOTAL_EVENTS = 2;
// Relaciones de Id con nomnbres
const Uint8 BITMAP0 = 0;
const Uint8 BITMAP1 = 1;
const Uint8 BITMAP2 = 2;
const Uint8 BITMAP3 = 3;
const Uint8 BITMAP4 = 4;
const Uint8 BITMAP5 = 5;
const Uint8 TEXT0 = 6;
const Uint8 TEXT1 = 7;
const Uint8 TEXT2 = 8;
const Uint8 TEXT3 = 9;
const Uint8 TEXT4 = 10;
const Uint8 TEXT5 = 11;
const Uint8 TEXT6 = 12;
const Uint8 TEXT7 = 13;
const Uint8 TEXT8 = 14;
// Anclajes para el marcador de puntos
const int SCORE_WORD_X = (SCREEN_WIDTH / 4) - ((5 * BLOCK) / 2);
const int SCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int SCORE_NUMBER_X = (SCREEN_WIDTH / 4) - ((6 * BLOCK) / 2);
const int SCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int HISCORE_WORD_X = ((SCREEN_WIDTH / 4) * 3) - ((8 * BLOCK) / 2);
const int HISCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int HISCORE_NUMBER_X = ((SCREEN_WIDTH / 4) * 3) - ((6 * BLOCK) / 2);
const int HISCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int MULTIPLIER_WORD_X = (SCREEN_WIDTH / 2) - ((4 * BLOCK) / 2);
const int MULTIPLIER_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int MULTIPLIER_NUMBER_X = (SCREEN_WIDTH / 2) - ((3 * BLOCK) / 2);
;
const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
// Ningun tipo
const Uint8 NO_KIND = 0;
// Tipos de globo
const Uint8 BALLOON_1 = 1;
const Uint8 BALLOON_2 = 2;
const Uint8 BALLOON_3 = 3;
const Uint8 BALLOON_4 = 4;
// Velocidad del globo
const float BALLON_VELX_POSITIVE = 0.7f;
const float BALLON_VELX_NEGATIVE = -0.7f;
// Indice para las animaciones de los globos
const Uint8 BALLOON_MOVING_ANIMATION = 0;
const Uint8 BALLOON_POP_ANIMATION = 1;
const Uint8 BALLOON_BORN_ANIMATION = 2;
// Cantidad posible de globos
const Uint8 MAX_BALLOONS = 75;
// Tipos de bala
const Uint8 BULLET_UP = 1;
const Uint8 BULLET_LEFT = 2;
const Uint8 BULLET_RIGHT = 3;
// Cantidad posible de globos
const Uint8 MAX_BULLETS = 50;
// Tipos de objetos
const Uint8 ITEM_POINTS_1_DISK = 1;
const Uint8 ITEM_POINTS_2_GAVINA = 2;
const Uint8 ITEM_POINTS_3_PACMAR = 3;
const Uint8 ITEM_CLOCK = 4;
const Uint8 ITEM_TNT = 5;
const Uint8 ITEM_COFFEE = 6;
// Cantidad de objetos simultaneos
const Uint8 MAX_ITEMS = 5;
// Valores para las variables asociadas a los objetos
const Uint8 REMAINING_EXPLOSIONS = 3;
const Uint8 REMAINING_EXPLOSIONS_TIMER = 50;
const Uint16 TIME_STOPPED_TIMER = 300;
// Estados de entrada
const Uint8 NO_INPUT = 0;
const Uint8 INPUT_UP = 1;
const Uint8 INPUT_DOWN = 2;
const Uint8 INPUT_LEFT = 3;
const Uint8 INPUT_RIGHT = 4;
const Uint8 INPUT_ACCEPT = 5;
const Uint8 INPUT_CANCEL = 6;
const Uint8 INPUT_FIRE_UP = 7;
const Uint8 INPUT_FIRE_LEFT = 8;
const Uint8 INPUT_FIRE_RIGHT = 9;
const Uint8 INPUT_PAUSE = 10;
// Zona muerta del mando analógico
const int JOYSTICK_DEAD_ZONE = 8000;
// Tipos de mensajes para el retorno de las funciones
const Uint8 MSG_OK = 0;
const Uint8 MSG_BULLET_OUT = 1;
// Tipos de texto
const Uint8 TEXT_FIXED = 0;
const Uint8 TEXT_VARIABLE = 1;
// Cantidad de elementos del vector de SmartSprites
const Uint8 MAX_SMART_SPRITES = 10;
// Contadores
const Uint16 TITLE_TIMER = 800;
const Uint8 STAGE_COUNTER = 200;
const Uint16 INSTRUCTIONS_COUNTER = 600;
const Uint16 DEATH_COUNTER = 350;
#endif

16
source/ifdefs.h Normal file
View File

@@ -0,0 +1,16 @@
#ifdef _WIN64
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include\SDL2\SDL.h"
#endif
#ifdef _WIN32
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include\SDL2\SDL.h"
#endif
#ifdef __APPLE__
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#endif
#ifdef __linux__
#include "/usr/include/SDL2/SDL.h"
#endif

212
source/jail_audio.cpp Normal file
View File

@@ -0,0 +1,212 @@
#include "jail_audio.h"
#include "stb_vorbis.c"
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
struct JA_Sound_t {
Uint32 length {0};
Uint8* buffer {NULL};
};
struct JA_Channel_t {
JA_Sound sound;
int pos {0};
int times {0};
JA_Channel_state state { JA_CHANNEL_FREE };
};
struct JA_Music_t {
int samples {0};
int pos {0};
int times {0};
short* output {NULL};
JA_Music_state state {JA_MUSIC_INVALID};
};
JA_Music current_music{NULL};
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2};
void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_memcpy(stream, current_music->output+current_music->pos, size);
current_music->pos += size/2;
if (size < len) {
if (current_music->times != 0) {
SDL_memcpy(stream+size, current_music->output, len-size);
current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--;
} else {
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
}
}
}
// 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, 64);
channels[i].pos += size;
if (size < len) {
if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, 64);
channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--;
} else {
JA_StopChannel(i);
}
}
}
}
}
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};
SDL_AudioDeviceID sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
SDL_PauseAudioDevice(sdlAudioDevice, 0);
}
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = (JA_Music)SDL_malloc(sizeof(JA_Music_t));
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
cvt.len = music->samples * chan * 2;
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->pos = 0;
music->state = JA_MUSIC_STOPPED;
return music;
}
void JA_PlayMusic(JA_Music music, const int loop) {
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;
}
void JA_PauseMusic() {
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PAUSED;
}
void JA_ResumeMusic() {
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PLAYING;
}
void JA_StopMusic() {
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
}
JA_Music_state JA_GetMusicState() {
if (current_music == NULL) return JA_MUSIC_INVALID;
return current_music->state;
}
void JA_DeleteMusic(JA_Music music) {
if (current_music == music) current_music = NULL;
free(music->output);
free(music);
}
JA_Sound JA_LoadSound(const char* filename) {
JA_Sound 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);
free(sound->buffer);
sound->buffer = cvt.buf;
sound->length = cvt.len_cvt;
return sound;
}
int JA_PlaySound(JA_Sound sound, const int loop) {
int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = JA_CHANNEL_PLAYING;
return channel;
}
void JA_DeleteSound(JA_Sound sound) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].sound == sound) JA_StopChannel(i);
}
SDL_FreeWAV(sound->buffer);
delete sound;
}
void JA_PauseChannel(const int channel) {
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) {
if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED;
}
}
void JA_ResumeChannel(const int channel) {
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;
}
} 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 (channel == -1) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
channels[i].state = JA_CHANNEL_FREE;
channels[i].pos = 0;
channels[i].sound = NULL;
}
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
channels[channel].state = JA_CHANNEL_FREE;
channels[channel].pos = 0;
channels[channel].sound = NULL;
}
}
JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state;
}

26
source/jail_audio.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include "ifdefs.h"
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
typedef struct JA_Sound_t *JA_Sound;
typedef struct JA_Music_t *JA_Music;
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
JA_Music JA_LoadMusic(const char* filename);
void JA_PlayMusic(JA_Music music, const int loop = -1);
void JA_PauseMusic();
void JA_ResumeMusic();
void JA_StopMusic();
JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music);
JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 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 sound);

160
source/ltexture.cpp Normal file
View File

@@ -0,0 +1,160 @@
#include <stdio.h>
#include <string>
#include "ltexture.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
LTexture::LTexture()
{
// Initialize
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
LTexture::~LTexture()
{
// Deallocate
free();
}
bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
{
int req_format = STBI_rgb_alpha;
int width, height, orig_format;
unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format);
if (data == NULL)
{
SDL_Log("Loading image failed: %s", stbi_failure_reason());
exit(1);
}
int depth, pitch;
Uint32 pixel_format;
if (req_format == STBI_rgb)
{
depth = 24;
pitch = 3 * width; // 3 bytes per pixel * pixels per row
pixel_format = SDL_PIXELFORMAT_RGB24;
}
else
{ // STBI_rgb_alpha (RGBA)
depth = 32;
pitch = 4 * width;
pixel_format = SDL_PIXELFORMAT_RGBA32;
}
// Get rid of preexisting texture
free();
// The final texture
SDL_Texture *newTexture = NULL;
// Load image at specified path
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void*)data, width, height, depth, pitch, pixel_format);
if (loadedSurface == NULL)
{
printf("Unable to load image %s!\n", path.c_str());
}
else
{
// Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL)
{
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
else
{
// Get image dimensions
mWidth = loadedSurface->w;
mHeight = loadedSurface->h;
}
// Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
// Return success
mTexture = newTexture;
return mTexture != NULL;
}
bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
{
// Create uninitialized texture
mTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (mTexture == NULL)
{
printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError());
}
else
{
mWidth = width;
mHeight = height;
}
return mTexture != NULL;
}
void LTexture::free()
{
// Free texture if it exists
if (mTexture != NULL)
{
SDL_DestroyTexture(mTexture);
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
}
void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{
// Modulate texture rgb
SDL_SetTextureColorMod(mTexture, red, green, blue);
}
void LTexture::setBlendMode(SDL_BlendMode blending)
{
// Set blending function
SDL_SetTextureBlendMode(mTexture, blending);
}
void LTexture::setAlpha(Uint8 alpha)
{
// Modulate texture alpha
SDL_SetTextureAlphaMod(mTexture, alpha);
}
void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, double angle, SDL_Point *center, SDL_RendererFlip flip)
{
// Set rendering space and render to screen
SDL_Rect renderQuad = {x, y, mWidth, mHeight};
// Set clip rendering dimensions
if (clip != NULL)
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
// Render to screen
SDL_RenderCopyEx(renderer, mTexture, clip, &renderQuad, angle, center, flip);
}
void LTexture::setAsRenderTarget(SDL_Renderer *renderer)
{
// Make self render target
SDL_SetRenderTarget(renderer, mTexture);
}
int LTexture::getWidth()
{
return mWidth;
}
int LTexture::getHeight()
{
return mHeight;
}

66
source/ltexture.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include "ifdefs.h"
#include <stdio.h>
#include <string>
#ifndef LTEXTURE_H
#define LTEXTURE_H
// Texture wrapper class
class LTexture
{
public:
// Initializes variables
LTexture();
// Deallocates memory
~LTexture();
// Loads image at specified path
bool loadFromFile(std::string path, SDL_Renderer *renderer);
// Creates blank texture
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
// Deallocates texture
void free();
// Set color modulation
void setColor(Uint8 red, Uint8 green, Uint8 blue);
// Set blending
void setBlendMode(SDL_BlendMode blending);
// Set alpha modulation
void setAlpha(Uint8 alpha);
// Renders texture at given point
void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = NULL, double angle = 0.0, SDL_Point *center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE);
// Set self as render target
void setAsRenderTarget(SDL_Renderer *renderer);
// Gets image dimensions
int getWidth();
int getHeight();
// Pixel manipulators
bool lockTexture();
bool unlockTexture();
void *getPixels();
void copyPixels(void *pixels);
int getPitch();
Uint32 getPixel32(unsigned int x, unsigned int y);
private:
// The actual hardware texture
SDL_Texture *mTexture;
void *mPixels;
int mPitch;
// Image dimensions
int mWidth;
int mHeight;
};
#endif

7762
source/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

5565
source/stb_vorbis.c Normal file

File diff suppressed because it is too large Load Diff

2330
source/volcano.cpp Normal file

File diff suppressed because it is too large Load Diff

209
source/volcano.h Normal file
View File

@@ -0,0 +1,209 @@
#pragma once
#ifndef VOLCANO_H
#define VOLCANO_H
#include "ifdefs.h"
#include "jail_audio.h"
#include "const.h"
#include "ltexture.h"
struct Tanimation
{
bool loops; // Salta a true cuando se reinicia la animación
Uint16 timer; // Temporizador de la animación
Uint8 frame[50]; // Vector con ....
Uint8 index; // Frame actual
Uint8 num_frames; // Cantidad de frames de la animación
Uint8 speed; // Velocidad de la animación
};
struct Tprogram
{
bool debug;
bool filter;
bool music_enabled; //
LTexture *sprite;
SDL_Rect dst_rect;
SDL_Rect src_rect;
Uint8 section;
};
struct Tgame
{
bool enabled;
Mix_Chunk *sound_drop_enemy;
Mix_Chunk *sound_drop_splat;
Mix_Music *music;
Uint8 zone; // Zona en la que estamos
};
struct Tmenu
{
bool enabled;
int frame;
int timer;
LTexture *sprite_animation;
LTexture *sprite;
Mix_Chunk *sound_logo;
Mix_Chunk *sound_start;
Mix_Music *music;
SDL_Rect dst_rect_animation;
SDL_Rect dst_rect_fondo;
SDL_Rect dst_rect_logo_zoom;
SDL_Rect dst_rect_logo;
SDL_Rect dst_rect_text;
SDL_Rect dst_rect_text2;
SDL_Rect src_rect_animation;
SDL_Rect src_rect_fondo;
SDL_Rect src_rect_logo;
SDL_Rect src_rect_text;
SDL_Rect src_rect_text2;
Tanimation animation[2];
Uint8 section;
};
struct Tplayer
{
bool can_jump; // Si puede saltar
bool enabled; // Si está habilitado
bool jump_pressed_before; // Si se ha pulsado el botón de salto previamente
bool jump_pressed_now; // Si se acaba de pulsar el salto
bool key[6]; // Indica las llaves que posee el jugador
bool standing; // Si esta de pie (o quieto?)
bool was_on_background; // Si viene de una zona atravesable
int coins; // Cantidad de monedas
int cooldown; // Tiempo de inhabilitación
int jumpforce; // Cantidad de pixels a desplazarse y velocidad que pilla al saltar
int respawn_x; // Coordenadas para revivir
int respawn_y; // Coordenades para revivir
int speed_x; // Cantidad de pixeles a desplazarse
int speed_y; // Cantidad de pixels a desplazarse
LTexture *sprite; // Textura con los graficos del jugador
Mix_Chunk *sound_coin; // Sonido al coger monedas
Mix_Chunk *sound_death; // Sonido al morir
Mix_Chunk *sound_jump; // Sonido al saltar
SDL_Rect dst_rect; // Rectangulo donde dibujar el sprite del jugador. Es la posición del jugador
SDL_Rect src_rect; // Rectangulo con el dibujo del jugador a pintar
Tanimation animation[8]; // Vector con las animaciones del jugador
Uint8 active_animation; // Animación activa
Uint8 direction; // Sentido del desplazamiento
Uint8 lifes; // Cantidad de vidas
Uint8 respawn_direction; // Dirección para revivir
};
struct Tactor
{
bool enabled;
Uint8 frame;
int speed_x;
int speed_y; // Velocidad = cantidad de pixeles a desplazarse
int timer;
SDL_Rect dst_rect;
SDL_Rect src_rect;
Uint8 direction; // Sentido del desplazamiento
Uint8 id;
Uint8 kind; // Tipo de actor: enemigo, moneda, llave, plataforma ...
Uint8 parent; // Indice al padre del actor
};
struct Tanimated_tile
{
bool enabled;
Uint8 index;
int x;
int y;
Uint8 frame;
};
struct Thud
{
LTexture *sprite;
SDL_Rect src_rect;
SDL_Rect dst_rect;
SDL_Rect num_src_rect;
SDL_Rect num_dst_rect;
SDL_Rect bignum_src_rect;
SDL_Rect bignum_dst_rect;
};
struct Tmap
{
LTexture *sprite_tile;
LTexture *sprite_actor;
LTexture *background;
SDL_Rect src_rect;
SDL_Rect dst_rect;
Uint8 *tile;
Uint8 *actor;
Uint8 w;
Uint8 h;
Uint8 room;
};
bool fullscreen;
bool quit;
const Uint8 *keys;
SDL_Event *event;
SDL_Renderer *renderer;
SDL_Window *window;
std::string executablePath;
Tactor actor[MAX_ACTORS];
Tanimated_tile animated_tile[MAX_ANIMATED_TILES];
Tgame game;
Thud hud;
Tmap map;
Tmenu menu;
Tplayer player;
Tprogram prog;
Uint32 delta_time;
bool CheckZoneChange(int room);
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer);
bool OnFloor();
Uint8 GetActor(Uint8 x, Uint8 y);
Uint8 GetTile(Uint8 x, Uint8 y);
Uint8 ReadMapTile(Uint8 x, Uint8 y);
void allocatePointers();
void Animate(Tanimation &a, SDL_Rect &s);
void AnimateIntroMenu(Tanimation &a, SDL_Rect &s);
void ApplyGravity();
void CheckPlayerCollisionWithActors();
void CheckPlayerCollisionWithActors();
void CheckPlayerCollisionWithMap();
void CloseMusic(Mix_Music *music);
void ClosePicture(LTexture *picture);
void CloseSound(Mix_Chunk *sound);
void CreateActor(Tactor &a, Uint8 kind, Uint8 id, Sint16 dstx, Sint16 dsty, Sint16 dstw, Sint16 dsth, Sint16 srcx, Sint16 srcy, Sint16 sx, Sint16 sy, Sint16 timer, Sint16 frame, Uint8 direction, Uint8 parent);
void DrawHud();
void DrawMap();
void DrawSprite(LTexture *sprite, SDL_Rect src_rect, SDL_Rect dst_rect);
void EndGame();
void EndHud();
void EndMap();
void EndMenu();
void EndPlayer();
void EndProgram();
void IniActors();
void IniAnimatedTiles();
void IniGame(Uint8 zone);
void IniHud();
void IniMap();
void IniMenu();
void IniPlayer();
void IniProgram();
void KillPlayer();
void LoadMap();
void LoadRoom(int num);
void MoveActors();
void MovePlayer(int direction);
void SetActor(Uint8 x, Uint8 y, Uint8 valor);
void setExecutablePath(std::string path);
void SetMapGFX(Uint8 zone);
void SetMapMusic(Uint8 zone);
void SetPlayerAnimation(Uint8 anim);
void SetPlayerDirection(int direction);
void SetProgSection(Uint8 section);
void SetZone(int room);
#endif