7 Commits

21 changed files with 330 additions and 137 deletions

3
.gitignore vendored
View File

@@ -9,3 +9,6 @@ scripts
todo.txt
data/config.bin
data/score.bin
*.opk
coffee_crisis
.vscode

View File

@@ -1,19 +0,0 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"intelliSenseMode": "macos-clang-x64",
"cStandard": "c11",
"cppStandard": "c++11"
}
],
"version": 4
}

21
.vscode/launch.json vendored
View File

@@ -1,21 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "g++ - Build and debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/coffee_crisis_macos_debug",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/bin",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: g++ build"
}
]
}

19
.vscode/settings.json vendored
View File

@@ -1,19 +0,0 @@
{
"files.associations": {
"cstddef": "cpp",
"__tuple": "cpp",
"array": "cpp",
"algorithm": "cpp",
"__bit_reference": "cpp",
"__hash_table": "cpp",
"__split_buffer": "cpp",
"initializer_list": "cpp",
"iterator": "cpp",
"string": "cpp",
"string_view": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"iosfwd": "cpp",
"stdexcept": "cpp"
}
}

31
.vscode/tasks.json vendored
View File

@@ -1,31 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++ build",
"command": "/usr/bin/g++",
"args": [
"-g",
"${workspaceFolder}/source/*.cpp",
"-std=c++11",
"-Wall",
"-O2",
"-lSDL2",
"-o",
"${workspaceFolder}/bin/coffee_crisis_macos_debug"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: /usr/bin/g++"
}
]
}

9
default.gcw0.desktop Normal file
View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=Coffee Crisis
Comment=Coffee Crisis
Icon=icon
Exec=bin/coffee_crisis
Categories=games;Game;SDL;
Terminal=false

7
generate_opendingux Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/bash
mkdir -p bin
cd source
/opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ -g -D_GCWZERO -O2 -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -std=c++11 *.cpp -o ../bin/coffee_crisis
cd ..
/opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./bin ./data ./media coffee_crisis.opk -all-root -noappend -no-exports -no-xattrs

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
media/.DS_Store vendored

Binary file not shown.

BIN
media/sound/clock.wav Normal file

Binary file not shown.

View File

@@ -56,4 +56,8 @@ bubble3.wav
JailDoctor
bubble4.wav
JailDoctor
JailDoctor
clock.wav
kenney_digitalaudio/switch2.ogg
www.kenney.nl

View File

@@ -38,8 +38,9 @@
#define SOUND_PLAYER_COLLISION 13
#define SOUND_STAGE_CHANGE 14
#define SOUND_TITLE 15
#define SOUND_CLOCK 16
#define TOTAL_SOUND 16
#define TOTAL_SOUND 17
#define TEXTURE_BALLOON 0
#define TEXTURE_BULLET 1

View File

@@ -2,6 +2,10 @@
#include "utils.h"
#include "gamedirector.h"
#include <iostream>
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
const Uint8 *keystates;
float mSin[360]; // Vector con los valores del seno para 360 grados
@@ -41,6 +45,18 @@ GameDirector::GameDirector(std::string path)
// Inicializa JailAudio
initJailAudio();
#ifdef __MIPSEL__
DIR *dir = opendir("/media/data/local/home/.coffee_crisis");
if (dir)
{
closedir(dir);
}
else if (ENOENT == errno)
{
int status = mkdir("/media/data/local/home/.coffee_crisis", 755);
}
#endif
// Carga recursos
loadMediaProg();
loadScoreFile();
@@ -129,9 +145,15 @@ void GameDirector::initProg()
mProg.keyboard.right = SDL_SCANCODE_RIGHT;
mProg.keyboard.accept = SDL_SCANCODE_RETURN;
mProg.keyboard.cancel = SDL_SCANCODE_ESCAPE;
#ifdef __MIPSEL__
mProg.keyboard.fire = SDL_SCANCODE_SPACE;
mProg.keyboard.fireLeft = SDL_SCANCODE_LSHIFT;
mProg.keyboard.fireRight = SDL_SCANCODE_LCTRL;
#else
mProg.keyboard.fire = SDL_SCANCODE_W;
mProg.keyboard.fireLeft = SDL_SCANCODE_Q;
mProg.keyboard.fireRight = SDL_SCANCODE_E;
#endif
mProg.keyboard.pause = SDL_SCANCODE_ESCAPE;
mProg.keyboard.escape = SDL_SCANCODE_ESCAPE;
@@ -1023,6 +1045,7 @@ bool GameDirector::loadMediaGame()
mSound[SOUND_BUBBLE2].sound = JA_LoadSound(mSound[SOUND_BUBBLE2].file.c_str());
mSound[SOUND_BUBBLE3].sound = JA_LoadSound(mSound[SOUND_BUBBLE3].file.c_str());
mSound[SOUND_BUBBLE4].sound = JA_LoadSound(mSound[SOUND_BUBBLE4].file.c_str());
mSound[SOUND_CLOCK].sound = JA_LoadSound(mSound[SOUND_CLOCK].file.c_str());
// Musicas
mMusic[MUSIC_PLAYING].music = JA_LoadMusic(mMusic[MUSIC_PLAYING].file.c_str());
@@ -1057,6 +1080,7 @@ void GameDirector::quitGame()
JA_DeleteSound(mSound[SOUND_BUBBLE2].sound);
JA_DeleteSound(mSound[SOUND_BUBBLE3].sound);
JA_DeleteSound(mSound[SOUND_BUBBLE4].sound);
JA_DeleteSound(mSound[SOUND_CLOCK].sound);
// Musicas
JA_DeleteMusic(mMusic[MUSIC_PLAYING].music);
@@ -1132,9 +1156,15 @@ void GameDirector::quitGame()
void GameDirector::setFileList()
{
// Ficheros binarios
#ifdef __MIPSEL__
mBinFile[BINFILE_SCORE].file = "/media/data/local/home/.coffee_crisis/score.bin";
mBinFile[BINFILE_DEMO].file = "/media/data/local/home/.coffee_crisis/demo.bin";
mBinFile[BINFILE_CONFIG].file = "/media/data/local/home/.coffee_crisis/config.bin";
#else
mBinFile[BINFILE_SCORE].file = mProg.executablePath + "/" + "../data/score.bin";
mBinFile[BINFILE_DEMO].file = mProg.executablePath + "/" + "../data/demo.bin";
mBinFile[BINFILE_CONFIG].file = mProg.executablePath + "/" + "../data/config.bin";
#endif
// Musicas
mMusic[MUSIC_INTRO].file = mProg.executablePath + "/" + "../media/music/intro.ogg";
@@ -1158,6 +1188,7 @@ void GameDirector::setFileList()
mSound[SOUND_PLAYER_COLLISION].file = mProg.executablePath + "/" + "../media/sound/player_collision.wav";
mSound[SOUND_STAGE_CHANGE].file = mProg.executablePath + "/" + "../media/sound/stage_change.wav";
mSound[SOUND_TITLE].file = mProg.executablePath + "/" + "../media/sound/title.wav";
mSound[SOUND_CLOCK].file = mProg.executablePath + "/" + "../media/sound/clock.wav";
// Texturas
mTexture[TEXTURE_BALLOON].file = mProg.executablePath + "/" + "../media/gfx/balloon.png";
@@ -3019,7 +3050,7 @@ void GameDirector::resetItems()
// Devuelve un item en función del azar
Uint8 GameDirector::dropItem()
{
//return ITEM_COFFEE;
return ITEM_COFFEE;
Uint8 luckyNumber = rand() % 99;
Uint8 item = rand() % 7;
@@ -3127,6 +3158,9 @@ void GameDirector::throwCoffee(int x, int y)
mGame.smartSprite[index]->setEnabled(true);
mGame.smartSprite[index]->setEnabledTimer(1);
mGame.smartSprite[index]->setSpriteClip(80, 16, 16, 16);
mGame.smartSprite[index]->setRotate(true);
mGame.smartSprite[index]->setRotateSpeed(1);
mGame.smartSprite[index]->setRotateAmount(5.0);
}
// Crea un SmartSprite para arrojar el item café al recibir un impacto
@@ -3986,6 +4020,17 @@ void GameDirector::renderMessages()
mText.black->writeCentered(PLAY_AREA_CENTER_X + 1, PLAY_AREA_FIRST_QUARTER_Y + 1, "Time Stopped: " + std::to_string(mGame.timeStoppedCounter / 10));
mText.white->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, "Time Stopped: " + std::to_string(mGame.timeStoppedCounter / 10));
}
if (mGame.timeStoppedCounter > 100)
{
if (mGame.timeStoppedCounter % 30 == 0)
JA_PlaySound(mSound[SOUND_CLOCK].sound, false);
}
else
{
if (mGame.timeStoppedCounter % 15 == 0)
JA_PlaySound(mSound[SOUND_CLOCK].sound, false);
}
}
// D E M O
@@ -4248,7 +4293,7 @@ void GameDirector::runIntro()
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
// Reproduce la música
JA_PlayMusic(mMusic[MUSIC_INTRO].music, false);
JA_PlayMusic(mMusic[MUSIC_INTRO].music, 0);
}
while ((mProg.section == PROG_SECTION_INTRO) && (!exit()))
@@ -4543,7 +4588,7 @@ void GameDirector::runTitle(Uint8 subsection)
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
// Reproduce la música
JA_PlayMusic(mMusic[MUSIC_TITLE].music, true);
JA_PlayMusic(mMusic[MUSIC_TITLE].music, -1);
}
// Calcula la lógica de los objetos
@@ -4745,7 +4790,7 @@ void GameDirector::runGame()
{
// Reproduce la música
if (mGame.player->isAlive())
JA_PlayMusic(mMusic[MUSIC_PLAYING].music, true);
JA_PlayMusic(mMusic[MUSIC_PLAYING].music, -1);
}
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego

View File

@@ -11,7 +11,11 @@
#endif
#ifdef __linux__
#include "/usr/include/SDL2/SDL.h"
#ifdef __MIPSEL__
#include "SDL.h"
#else
#include <SDL2/SDL.h>
#endif
#endif
#define UNUSED

View File

@@ -1,6 +1,6 @@
#ifndef __MIPSEL__
#include "jail_audio.h"
#include "stb_vorbis.c"
//#include <SDL2/SDL.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
@@ -210,4 +210,4 @@ JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state;
}
#endif

View File

@@ -0,0 +1,106 @@
#ifdef __MIPSEL__
#include "jail_audio.h"
#include "SDL_mixer.h"
struct JA_Sound_t {
Mix_Chunk *mix_chunk;
};
struct JA_Music_t {
Mix_Music* mix_music;
};
JA_Music current_music{NULL};
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
Mix_AllocateChannels(8);
}
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = new JA_Music_t();
music->mix_music = Mix_LoadMUS(filename);
return music;
}
void JA_PlayMusic(JA_Music music, const int loop) {
if (current_music == music) return;
if (current_music != NULL) {
Mix_HaltMusic();
}
current_music = music;
Mix_PlayMusic(music->mix_music, loop);
}
void JA_PauseMusic() {
Mix_PauseMusic();
}
void JA_ResumeMusic() {
Mix_ResumeMusic();
}
void JA_StopMusic() {
Mix_HaltMusic();
}
JA_Music_state JA_GetMusicState() {
if (current_music == NULL) return JA_MUSIC_INVALID;
if (Mix_PausedMusic()) {
return JA_MUSIC_PAUSED;
} else if (Mix_PlayingMusic()) {
return JA_MUSIC_PLAYING;
} else {
return JA_MUSIC_STOPPED;
}
}
void JA_DeleteMusic(JA_Music music) {
if (current_music == music) {
Mix_HaltMusic();
current_music = NULL;
}
Mix_FreeMusic(music->mix_music);
delete music;
}
JA_Sound JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t();
sound->mix_chunk = Mix_LoadWAV(filename);
return sound;
}
int JA_PlaySound(JA_Sound sound, const int loop) {
int channel = Mix_PlayChannel(-1, sound->mix_chunk, loop);
return channel;
}
void JA_DeleteSound(JA_Sound sound) {
Mix_FreeChunk(sound->mix_chunk);
delete sound;
}
void JA_PauseChannel(const int channel) {
Mix_Pause(channel);
}
void JA_ResumeChannel(const int channel) {
Mix_Resume(channel);
}
void JA_StopChannel(const int channel) {
Mix_HaltChannel(channel);
}
JA_Channel_state JA_GetChannelState(const int channel) {
if (Mix_Paused(channel)) {
return JA_CHANNEL_PAUSED;
} else if (Mix_Playing(channel)) {
return JA_CHANNEL_PLAYING;
} else {
return JA_CHANNEL_FREE;
}
}
#endif

View File

@@ -37,6 +37,9 @@ void MovingSprite::init(float x, float y, int w, int h, float velx, float vely,
setZoomW(1);
setZoomH(1);
// Establece el angulo con el que se dibujará
setAngle(0.0);
// Establece la textura donde están los gráficos para el sprite
setTexture(texture);
@@ -61,57 +64,63 @@ void MovingSprite::move()
void MovingSprite::render()
{
//mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip);
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH);
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle);
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getPosX()
{
return mPosX;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getPosY()
{
return mPosY;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getVelX()
{
return mVelX;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getVelY()
{
return mVelY;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getAccelX()
{
return mAccelX;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getAccelY()
{
return mAccelY;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getZoomW()
{
return mZoomW;
}
// Establece el valor de la variable
// Obtiene el valor de la variable
float MovingSprite::getZoomH()
{
return mZoomH;
}
// Obtiene el valor de la variable
double MovingSprite::getAngle()
{
return mAngle;
}
// Establece el valor de la variable
void MovingSprite::setPosX(float x)
{
@@ -158,4 +167,22 @@ void MovingSprite::setZoomW(float w)
void MovingSprite::setZoomH(float h)
{
mZoomH = h;
}
// Establece el valor de la variable
void MovingSprite::setAngle(double a)
{
mAngle = a;
}
// Incrementa el valor de la variable
void MovingSprite::incAngle(double inc)
{
mAngle += inc;
}
// Decrementa el valor de la variable
void MovingSprite::decAngle(double dec)
{
mAngle -= dec;
}

View File

@@ -21,6 +21,8 @@ private:
float mZoomW; // Zoom aplicado a la anchura
float mZoomH; // Zoom aplicado a la altura
double mAngle; // Angulo para dibujarlo
public:
// Constructor
MovingSprite();
@@ -61,6 +63,9 @@ public:
// Obten el valor de la variable
float getZoomH();
// Obten el valor de la variable
double getAngle();
// Establece el valor de la variable
void setPosX(float x);
@@ -84,6 +89,15 @@ public:
// Establece el valor de la variable
void setZoomH(float h);
// Establece el valor de la variable
void setAngle(double a);
// Incrementa el valor de la variable
void incAngle(double inc);
// Decrementa el valor de la variable
void decAngle(double dec);
};
#endif

View File

@@ -38,6 +38,12 @@ void SmartSprite::init(LTexture *texture, SDL_Renderer *renderer)
mDestX = 0;
mDestY = 0;
setRotate(false);
setRotateSpeed(0);
setRotateAmount(0.0);
mCounter = 0;
// El Id siempre es >=0, por lo tanto si no se le asigna Id se queda en negativo
mId = -1;
@@ -65,13 +71,13 @@ void SmartSprite::setEnabled(bool state)
// Obtiene el valor de la variable
Uint16 SmartSprite::getEnabledTimer()
{
return mEnabledTimer;
return mEnabledCounter;
}
// Establece el valor de la variable
void SmartSprite::setEnabledTimer(Uint16 time)
{
mEnabledTimer = time;
mEnabledCounter = time;
}
// Establece el valor de la variable
@@ -86,6 +92,24 @@ void SmartSprite::setDestY(int value)
mDestY = value;
}
// Establece el valor de la variable
void SmartSprite::setRotate(bool value)
{
mRotate = value;
}
// Establece el valor de la variable
void SmartSprite::setRotateSpeed(Uint16 value)
{
mRotateSpeed = value;
}
// Establece el valor de la variable
void SmartSprite::setRotateAmount(double value)
{
mRotateAmount = value;
}
// Obtiene el valor de la variable
int SmartSprite::getDestX()
{
@@ -98,12 +122,37 @@ int SmartSprite::getDestY()
return mDestY;
}
// Obtiene el valor de la variable
bool SmartSprite::getRotate()
{
return mRotate;
}
// Obtiene el valor de la variable
Uint16 SmartSprite::getRotateSpeed()
{
return mRotateSpeed;
}
// Establece la rotacion
void SmartSprite::rotate()
{
if (mRotate)
{
if (mCounter % mRotateSpeed == 0)
{
incAngle(mRotateAmount);
}
}
}
// Actualiza la posición y comprueba si ha llegado a su destino
bool SmartSprite::update()
{
if (mEnabled)
{
move();
rotate();
// Comprueba si se desplaza en el eje X hacia la derecha
if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0)))
@@ -178,12 +227,12 @@ bool SmartSprite::update()
if (mIsOnDestination)
{
// Si el contador es mayor que cero, lo decrementa
if (mEnabledTimer > 0)
if (mEnabledCounter > 0)
{
--mEnabledTimer;
--mEnabledCounter;
}
// Si ha llegado a cero, deshabilita el objeto o manda el aviso en función de si tiene Id
else if (mEnabledTimer == 0)
else if (mEnabledCounter == 0)
{
if (mId < 0)
{
@@ -195,6 +244,9 @@ bool SmartSprite::update()
}
}
}
mCounter++;
mCounter %= 65000;
}
return mIsOnDestination;

View File

@@ -8,6 +8,19 @@
// Clase SmartSprite
class SmartSprite : public AnimatedSprite
{
private:
bool mEnabled; // Indica si esta habilitado
bool mIsOnDestination; // Indica si está en el destino
bool mRotate; // Indica si ha de rotar
int mDestX; // Posicion de destino en el eje X
int mDestY; // Posicion de destino en el eje Y
int mId; // Identificador
Uint16 mCounter; // Contador interno
Uint16 mEnabledCounter; // Contador para deshabilitarlo
Uint16 mRotateSpeed; // Velocidad de giro
Uint8 *mIntroEvents; // Dirección del array de eventos donde notificar el estado
double mRotateAmount; // Cantidad de grados a girar en cada iteración
public:
// Constructor
SmartSprite();
@@ -39,15 +52,33 @@ public:
// Establece el valor de la variable
void setDestY(int value);
// Establece el valor de la variable
void setRotate(bool value);
// Establece el valor de la variable
void setRotateSpeed(Uint16 value);
// Establece el valor de la variable
void setRotateAmount(double value);
// Obtiene el valor de la variable
int getDestX();
// Obtiene el valor de la variable
int getDestY();
// Obtiene el valor de la variable
bool getRotate();
// Obtiene el valor de la variable
Uint16 getRotateSpeed();
// Establece la rotacion
void rotate();
// Actualiza la posición y comprueba si ha llegado a su destino
bool update();
// Obtiene el valor de la variable
bool isOnDestination();
@@ -59,26 +90,6 @@ public:
// Establece el valor de la variable
void setIntroEvents(Uint8 *value);
private:
// Indica si esta habilitado
bool mEnabled;
// Contador
Uint16 mEnabledTimer;
// Indica si está en el destino
bool mIsOnDestination;
// Posicion de destino
int mDestX;
int mDestY;
// Identificador
int mId;
// Dirección del array de eventos donde notificar el estado
Uint8 *mIntroEvents;
};
#endif

View File

@@ -26,11 +26,11 @@ fi
# UPLOAD
if [ "$1" = upload ] || [ "$1" = UPLOAD ]; then
printf "\n%s\n" "uploading $PROJECT"
rsync -azmPu --delete -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT/
rsync -azmPu -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT.all/
rsync -avzmPu --delete -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT/
rsync -avzmPu -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT.all/
fi
if [ "$1" = download ] || [ "$1" = DOWNLOAD ]; then
printf "%s\n" "downloading $PROJECT"
rsync -azmP --delete -e 'ssh -p 4545' sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT/* .
rsync -avzmP --delete -e 'ssh -p 4545' sergio@sustancia.synology.me:/home/sergio/backup/code/$PROJECT/* .
fi