Created
June 22, 2019 19:31
-
-
Save savolla/bdf18fed31392639a007a2fa38718002 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*This source code copyrighted by Lazy Foo' Productions (2004-2019) | |
and may not be redistributed without written permission.*/ | |
//Using SDL, SDL_image, SDL_ttf, SDL_mixer, standard IO, math, and strings | |
#include <SDL2/SDL.h> | |
#include <SDL2/SDL_image.h> | |
#include <SDL2/SDL_mixer.h> | |
#include <stdio.h> | |
#include <string> | |
//Screen dimension constants | |
const int SCREEN_WIDTH = 640; | |
const int SCREEN_HEIGHT = 480; | |
//Texture wrapper class | |
class LTexture | |
{ | |
public: | |
//Initializes variables | |
LTexture(); | |
//Deallocates memory | |
~LTexture(); | |
//Loads image at specified path | |
bool loadFromFile( std::string path ); | |
#if defined(_SDL_TTF_H) || defined(SDL_TTF_H) | |
//Creates image from font string | |
bool loadFromRenderedText( std::string textureText, SDL_Color textColor ); | |
#endif | |
//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( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE ); | |
//Gets image dimensions | |
int getWidth(); | |
int getHeight(); | |
private: | |
//The actual hardware texture | |
SDL_Texture* mTexture; | |
//Image dimensions | |
int mWidth; | |
int mHeight; | |
}; | |
//Starts up SDL and creates window | |
bool init(); | |
//Loads media | |
bool loadMedia(); | |
//Frees media and shuts down SDL | |
void close(); | |
//The window we'll be rendering to | |
SDL_Window* gWindow = NULL; | |
//The window renderer | |
SDL_Renderer* gRenderer = NULL; | |
//Scene texture | |
LTexture gPromptTexture; | |
//The music that will be played | |
Mix_Music *gMusic = NULL; | |
//The sound effects that will be used | |
Mix_Chunk *gScratch = NULL; | |
Mix_Chunk *gHigh = NULL; | |
Mix_Chunk *gMedium = NULL; | |
Mix_Chunk *gLow = NULL; | |
LTexture::LTexture() | |
{ | |
//Initialize | |
mTexture = NULL; | |
mWidth = 0; | |
mHeight = 0; | |
} | |
LTexture::~LTexture() | |
{ | |
//Deallocate | |
free(); | |
} | |
bool LTexture::loadFromFile( std::string path ) | |
{ | |
//Get rid of preexisting texture | |
free(); | |
//The final texture | |
SDL_Texture* newTexture = NULL; | |
//Load image at specified path | |
SDL_Surface* loadedSurface = IMG_Load( path.c_str() ); | |
if( loadedSurface == NULL ) | |
{ | |
printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() ); | |
} | |
else | |
{ | |
//Color key image | |
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0, 0xFF, 0xFF ) ); | |
//Create texture from surface pixels | |
newTexture = SDL_CreateTextureFromSurface( gRenderer, 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; | |
} | |
#if defined(_SDL_TTF_H) || defined(SDL_TTF_H) | |
bool LTexture::loadFromRenderedText( std::string textureText, SDL_Color textColor ) | |
{ | |
//Get rid of preexisting texture | |
free(); | |
//Render text surface | |
SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor ); | |
if( textSurface != NULL ) | |
{ | |
//Create texture from surface pixels | |
mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface ); | |
if( mTexture == NULL ) | |
{ | |
printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); | |
} | |
else | |
{ | |
//Get image dimensions | |
mWidth = textSurface->w; | |
mHeight = textSurface->h; | |
} | |
//Get rid of old surface | |
SDL_FreeSurface( textSurface ); | |
} | |
else | |
{ | |
printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); | |
} | |
//Return success | |
return mTexture != NULL; | |
} | |
#endif | |
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( 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( gRenderer, mTexture, clip, &renderQuad, angle, center, flip ); | |
} | |
int LTexture::getWidth() | |
{ | |
return mWidth; | |
} | |
int LTexture::getHeight() | |
{ | |
return mHeight; | |
} | |
bool init() | |
{ | |
//Initialization flag | |
bool success = true; | |
//Initialize SDL | |
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) | |
{ | |
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() ); | |
success = false; | |
} | |
else | |
{ | |
//Set texture filtering to linear | |
if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) ) | |
{ | |
printf( "Warning: Linear texture filtering not enabled!" ); | |
} | |
//Create window | |
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); | |
if( gWindow == NULL ) | |
{ | |
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() ); | |
success = false; | |
} | |
else | |
{ | |
//Create vsynced renderer for window | |
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC ); | |
if( gRenderer == NULL ) | |
{ | |
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() ); | |
success = false; | |
} | |
else | |
{ | |
//Initialize renderer color | |
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); | |
//Initialize PNG loading | |
int imgFlags = IMG_INIT_PNG; | |
if( !( IMG_Init( imgFlags ) & imgFlags ) ) | |
{ | |
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() ); | |
success = false; | |
} | |
//Initialize SDL_mixer | |
if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) < 0 ) | |
{ | |
printf( "SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
} | |
} | |
} | |
return success; | |
} | |
bool loadMedia() | |
{ | |
//Loading success flag | |
bool success = true; | |
//Load prompt texture | |
if( !gPromptTexture.loadFromFile( "21_sound_effects_and_music/prompt.png" ) ) | |
{ | |
printf( "Failed to load prompt texture!\n" ); | |
success = false; | |
} | |
//Load music | |
gMusic = Mix_LoadMUS( "21_sound_effects_and_music/beat.wav" ); | |
if( gMusic == NULL ) | |
{ | |
printf( "Failed to load beat music! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
//Load sound effects | |
gScratch = Mix_LoadWAV( "21_sound_effects_and_music/scratch.wav" ); | |
if( gScratch == NULL ) | |
{ | |
printf( "Failed to load scratch sound effect! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
gHigh = Mix_LoadWAV( "21_sound_effects_and_music/high.wav" ); | |
if( gHigh == NULL ) | |
{ | |
printf( "Failed to load high sound effect! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
gMedium = Mix_LoadWAV( "21_sound_effects_and_music/medium.wav" ); | |
if( gMedium == NULL ) | |
{ | |
printf( "Failed to load medium sound effect! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
gLow = Mix_LoadWAV( "21_sound_effects_and_music/low.wav" ); | |
if( gLow == NULL ) | |
{ | |
printf( "Failed to load low sound effect! SDL_mixer Error: %s\n", Mix_GetError() ); | |
success = false; | |
} | |
return success; | |
} | |
void close() | |
{ | |
//Free loaded images | |
gPromptTexture.free(); | |
//Free the sound effects | |
Mix_FreeChunk( gScratch ); | |
Mix_FreeChunk( gHigh ); | |
Mix_FreeChunk( gMedium ); | |
Mix_FreeChunk( gLow ); | |
gScratch = NULL; | |
gHigh = NULL; | |
gMedium = NULL; | |
gLow = NULL; | |
//Free the music | |
Mix_FreeMusic( gMusic ); | |
gMusic = NULL; | |
//Destroy window | |
SDL_DestroyRenderer( gRenderer ); | |
SDL_DestroyWindow( gWindow ); | |
gWindow = NULL; | |
gRenderer = NULL; | |
//Quit SDL subsystems | |
Mix_Quit(); | |
IMG_Quit(); | |
SDL_Quit(); | |
} | |
int main( int argc, char* args[] ) | |
{ | |
//Start up SDL and create window | |
if( !init() ) | |
{ | |
printf( "Failed to initialize!\n" ); | |
} | |
else | |
{ | |
//Load media | |
if( !loadMedia() ) | |
{ | |
printf( "Failed to load media!\n" ); | |
} | |
else | |
{ | |
//Main loop flag | |
bool quit = false; | |
//Event handler | |
SDL_Event e; | |
//While application is running | |
while( !quit ) | |
{ | |
//Handle events on queue | |
while( SDL_PollEvent( &e ) != 0 ) | |
{ | |
//User requests quit | |
if( e.type == SDL_QUIT ) | |
{ | |
quit = true; | |
} | |
//Handle key press | |
else if( e.type == SDL_KEYDOWN ) | |
{ | |
switch( e.key.keysym.sym ) | |
{ | |
//Play high sound effect | |
case SDLK_1: | |
Mix_PlayChannel( -1, gHigh, 0 ); | |
break; | |
//Play medium sound effect | |
case SDLK_2: | |
Mix_PlayChannel( -1, gMedium, 0 ); | |
break; | |
//Play low sound effect | |
case SDLK_3: | |
Mix_PlayChannel( -1, gLow, 0 ); | |
break; | |
//Play scratch sound effect | |
case SDLK_4: | |
Mix_PlayChannel( -1, gScratch, 0 ); | |
break; | |
case SDLK_9: | |
//If there is no music playing | |
if( Mix_PlayingMusic() == 0 ) | |
{ | |
//Play the music | |
Mix_PlayMusic( gMusic, -1 ); | |
} | |
//If music is being played | |
else | |
{ | |
//If the music is paused | |
if( Mix_PausedMusic() == 1 ) | |
{ | |
//Resume the music | |
Mix_ResumeMusic(); | |
} | |
//If the music is playing | |
else | |
{ | |
//Pause the music | |
Mix_PauseMusic(); | |
} | |
} | |
break; | |
case SDLK_0: | |
//Stop the music | |
Mix_HaltMusic(); | |
break; | |
} | |
} | |
} | |
//Clear screen | |
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); | |
SDL_RenderClear( gRenderer ); | |
//Render prompt | |
gPromptTexture.render( 0, 0 ); | |
//Update screen | |
SDL_RenderPresent( gRenderer ); | |
} | |
} | |
} | |
//Free resources and close SDL | |
close(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment