diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | manifest.scm | 1 | ||||
-rw-r--r-- | src/main.cpp | 132 | ||||
-rw-r--r-- | src/renderer.cpp | 37 | ||||
-rw-r--r-- | src/renderer.h | 15 | ||||
-rw-r--r-- | src/texture.cpp | 46 | ||||
-rw-r--r-- | src/texture.h | 15 | ||||
-rw-r--r-- | src/timer.cpp | 19 | ||||
-rw-r--r-- | src/timer.h | 15 | ||||
-rw-r--r-- | src/window.cpp | 58 | ||||
-rw-r--r-- | src/window.h | 27 |
12 files changed, 392 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25e7a68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/* +tetris diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3b2fa99 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +CC = g++ +CFLAGS = -Wall + +TARGET = tetris + +SRCDIR = src + +OBJDIR = build +BASENM = $(notdir $(basename $(wildcard src/*.cpp))) +OBJS = $(addsuffix .o, $(addprefix $(OBJDIR)/, $(BASENM)) ) + + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(OBJS) -o $(TARGET) -lSDL2 -lSDL2_image + +$(OBJS): $(OBJDIR)/%.o: $(SRCDIR)/%.cpp + mkdir -p $(OBJDIR) + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -r $(OBJDIR) $(TARGET) + +.PHONY: all clean diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..3606f15 --- /dev/null +++ b/manifest.scm @@ -0,0 +1 @@ +(specifications->manifest '("sdl2" "sdl2-image" "gcc-toolchain" "gdb" "man-db")) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..422fdc3 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,132 @@ +//Using SDL and standard IO +#include <SDL2/SDL.h> +#include <stdio.h> +#include "texture.h" +#include "renderer.h" +#include "window.h" +#include "timer.h" + +#include <chrono> +#include <thread> +//void millisleep(Uint32 t){ +// SDL_Delay(t); +//} + +//Screen dimension constants +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; +const int WALKING_ANIMATION_FRAMES = 7; + +void loop( Renderer &renderer, Texture &gSpriteSheetTexture, SDL_Rect* gSpriteClips, Uint32 dt){ + static int frame; + + renderer.clear(); + SDL_Rect* currentClip = &gSpriteClips[ frame / WALKING_ANIMATION_FRAMES ]; + + + // Txanpona mugitu: + float vx = 100; // px/s + static float xpos0; + float xpos = xpos0 + dt/1000.f * vx; + xpos0 = xpos; + + float g = 75; // px/(s^2) + static float vy0 = 100; // px/s + static float ypos0; + float vy = vy0 -(dt/1000.f * g) ; + float ypos = ypos0 + dt/1000.f * vy; + ypos0 = ypos; + vy0 = vy; + if ( ypos0 < 0 ) { ypos0 = 0; } + if ( ypos < 0 ) { ypos = 0; } + + gSpriteSheetTexture.render(xpos, (SCREEN_HEIGHT/2 -20) - ypos, currentClip); + + //Update screen + renderer.update(); + ++frame; + + //Cycle animation + if( frame / WALKING_ANIMATION_FRAMES >= WALKING_ANIMATION_FRAMES ) + { + frame = 0; + } + return; + +} + +int +main( int argc, char* args[] ) { + + if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) + { + printf( "SDL could not initialize: %s\n", SDL_GetError() ); + } + + Window window {"This is the title", SCREEN_WIDTH, SCREEN_HEIGHT}; + Renderer renderer; + renderer.init(window.window()); + renderer.setScale(2,2); + + + //The window we'll be rendering to + SDL_Rect gSpriteClips[ WALKING_ANIMATION_FRAMES ]; + Texture gSpriteSheetTexture {renderer.renderer()}; + + + //Load sprite sheet texture + if(-1 ==gSpriteSheetTexture.loadFromFile( "assets/money.png" ) ) + { + return -1; + } + else + { + for( int i =0; i < WALKING_ANIMATION_FRAMES; i++){ + //Set sprite clips + gSpriteClips[ i ].x = i*16; + gSpriteClips[ i ].y = 0; + gSpriteClips[ i ].w = 16; + gSpriteClips[ i ].h = 16; + } + } + + + // BODY + /////////////////////////////////////////////////////////////////////////// + const Uint32 LOOP_TIME = 20L; // milliseconds + Timer timer; + timer.start(); + while( true ) + { + // Handle events + SDL_Event e; + while( SDL_PollEvent( &e ) != 0 ) + { + //User requests quit + window.handleEvent(e); + if( e.type == SDL_QUIT ) { + return 0; + } else if (e.type == SDL_KEYDOWN){ + switch( e.key.keysym.sym ){ + case 'q': + return 0; + } + } + } + + if(window.closed()) return 0; + if(!window.focused()) goto next; + + + // GAME LOOP: + loop(renderer, gSpriteSheetTexture, gSpriteClips, timer.elapsed()); + + // Loop time calculation: + next: + timer.restart(); + timer.waitUntil( LOOP_TIME ); + } + + SDL_Quit(); + return 0; +} diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..2f90a8d --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,37 @@ +#include "renderer.h" + +Renderer::Renderer(){ + renderer_ = nullptr; +} + +Renderer::~Renderer(){ + SDL_DestroyRenderer(renderer_); +} + +void Renderer::init( SDL_Window* win ) { + if (renderer_){ + SDL_DestroyRenderer(renderer_); + } + renderer_ = SDL_CreateRenderer( win, -1, SDL_RENDERER_ACCELERATED); + if (renderer_ == NULL){ + printf("Unable to create rendering context: %s", SDL_GetError()); + } +} + +void Renderer::clear(){ + SDL_RenderClear(renderer_); +} +void Renderer::update(){ + SDL_RenderPresent(renderer_); +} + +SDL_Renderer * Renderer::renderer(){ + return renderer_; +} + +void Renderer::setScale(int scaleX, int scaleY){ + if( SDL_RenderSetScale(renderer_, scaleX, scaleY) < 0){ + printf("Unable to set scale in renderer: %s", SDL_GetError()); + } +} + diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..b76b831 --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,15 @@ +#include <SDL2/SDL.h> + +class Renderer{ + + public: + Renderer(); + ~Renderer(); + void init(SDL_Window* win); + void clear(); + void update(); + SDL_Renderer* renderer(); + void setScale(int scaleX, int scaleY); + private: + SDL_Renderer* renderer_; +}; diff --git a/src/texture.cpp b/src/texture.cpp new file mode 100644 index 0000000..6657a4a --- /dev/null +++ b/src/texture.cpp @@ -0,0 +1,46 @@ +#include <SDL2/SDL_image.h> +#include "texture.h" + +Texture::Texture(SDL_Renderer* renderer): + texture_(nullptr), + w_(0), + h_(0), + renderer_ (renderer){ +} + +Texture::~Texture(){ + if(texture_){ + SDL_DestroyTexture(texture_); + } +} + +int Texture::loadFromFile(std::string path){ + SDL_Surface* Loading_Surf = IMG_Load(path.c_str()); + if(Loading_Surf == NULL){ + printf("Failed to load surface: %s\n", SDL_GetError()); + return -1; + } + texture_ = SDL_CreateTextureFromSurface(renderer_, Loading_Surf); + if(texture_ == NULL){ + printf("Failed to create texture: %s\n", SDL_GetError()); + return -1; + } + SDL_FreeSurface(Loading_Surf); + w_ = Loading_Surf->w; + h_ = Loading_Surf->h; + return 0; +} + +void Texture::render(int x, int y, SDL_Rect* clip){ + SDL_Rect renderQuad = { x, y, w_, h_ }; + + //Set clip rendering dimensions + if( clip ) + { + renderQuad.w = clip->w; + renderQuad.h = clip->h; + } + + //Render to screen + SDL_RenderCopy( renderer_, texture_, clip, &renderQuad ); +} diff --git a/src/texture.h b/src/texture.h new file mode 100644 index 0000000..311db4a --- /dev/null +++ b/src/texture.h @@ -0,0 +1,15 @@ +#include <SDL2/SDL.h> +#include <string> + +class Texture{ + public: + Texture(SDL_Renderer* renderer); + ~Texture(); + int loadFromFile(std::string path); + void render(int x, int y, SDL_Rect* clip = nullptr); + private: + SDL_Texture* texture_; + int w_; + int h_; + SDL_Renderer* renderer_; +}; diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000..c775a73 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,19 @@ +#include "timer.h" + +Timer::Timer(): t0 {0} {} + +void Timer::start(){ + t0 = SDL_GetTicks(); +} +unsigned int Timer::elapsed(){ + return SDL_GetTicks() - t0; +} +void Timer::restart(){ + start(); +} +void Timer::wait(unsigned int millis){ + SDL_Delay(millis); +} +void Timer::waitUntil(unsigned int millis){ + wait( millis - elapsed() ); +} diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..3c714a9 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,15 @@ +#include<SDL2/SDL.h> +class Timer{ + + public: + Timer(); + + void start(); + unsigned int elapsed(); + void restart(); + void wait(unsigned int millis); + void waitUntil(unsigned int millis); + + private: + Uint32 t0; +}; diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..39cbc3d --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,58 @@ +#include "window.h" + +Window::Window( const char* title, int w, int h, int x, int y ) + : closed_ {false}, + focused_ {true} { + window_ = SDL_CreateWindow( title, x, y, w, h, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE ); + if( window_ == NULL ) + { + printf( "Window could not be created: %s\n", SDL_GetError() ); + } +} + +Window::~Window(){ + SDL_DestroyWindow( window_ ); +} + +SDL_Window* Window::window(){ + return window_; +} + +void Window::toggleFullscreen(){ + auto togg = SDL_TRUE; + if( fullscreen_ ){ + togg = SDL_FALSE; + } + SDL_SetWindowFullscreen( window_, togg ); + printf("toggling fullscreen\n"); + fullscreen_ = !fullscreen_; +} + +void Window::handleEvent(SDL_Event e){ + switch( e.window.event ){ + case SDL_WINDOWEVENT_CLOSE: + closed_ = true; + printf("CLOSE!"); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + focused_ = true; + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + focused_ = false; + break; + } +} + +Point Window::getSize(){ + Point size; + SDL_GetWindowSize(window_, &size.x, &size.y); + return size; +} + +bool Window::focused(){ + return focused_; +} + +bool Window::closed(){ + return closed_; +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..efa2165 --- /dev/null +++ b/src/window.h @@ -0,0 +1,27 @@ +#include<SDL2/SDL.h> + +struct Point{ + int x, y; +}; + +class Window{ + + public: + Window( const char * title, + int w, + int h, + int x = SDL_WINDOWPOS_UNDEFINED, + int y = SDL_WINDOWPOS_UNDEFINED ); + ~Window(); + SDL_Window* window(); + void handleEvent( SDL_Event e ); + void toggleFullscreen(); + Point getSize(); + bool closed(); + bool focused(); + private: + SDL_Window* window_; + bool fullscreen_; + bool focused_; + bool closed_; +}; |