summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2021-12-23 20:52:49 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2021-12-23 20:52:49 +0100
commit35465f27ed87646a18cd9298eae861f14385300e (patch)
tree7f0256d28fa6fd5368b7a39500d080456e70be8e
First commit: moves a simple thing on the screen
-rw-r--r--.gitignore2
-rw-r--r--Makefile25
-rw-r--r--manifest.scm1
-rw-r--r--src/main.cpp132
-rw-r--r--src/renderer.cpp37
-rw-r--r--src/renderer.h15
-rw-r--r--src/texture.cpp46
-rw-r--r--src/texture.h15
-rw-r--r--src/timer.cpp19
-rw-r--r--src/timer.h15
-rw-r--r--src/window.cpp58
-rw-r--r--src/window.h27
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_;
+};