diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e87951c --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +# THIS IS THE MAKE FILE FOR TURNING +# ALL C FILES INTO BINARIES + +# VARIABLES +LIBS = -lsdl2main -lsdl2_ttf -lsdl2_image -lsdl2_mixer -lsdl2 + +# COMPILING +all: CLS compile link install clean + +CLS: + clear + +compile: + gcc -c -I inc src/app/*.c + gcc -c -I inc src/gme/*.c + gcc -c -I inc src/scn/*.c + gcc -c -I inc src/*.c + +link: + gcc *.o -L lib $(LIBS) -o bin/blokos + +install: + cp -vr res bin + +clean: + rm *.o + +run: + ./bin/blokos \ No newline at end of file diff --git a/README.md b/README.md index 8118ad0..6eaffe9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,66 @@ -# Blokos +# BLOKOS # +### By Maddox Werts. ### -Tetris in C \ No newline at end of file +## What is this? ## +This is a simple Computer Science project I'll be working on +for the following 5 days as instructed. This project is using +the C language, so code will make more sense in this. +Also, To pronounce it, it's BLOCK * OU * SS + +## Why not C++? ## +I wanted to challange myself, I'm going to use C because +it's an older language, and one of the Most popular. + +## How can I play BLOKOS? ## +There will be Two methods! +- [Downloading from the Releases Page](https://github.com/Maddox-Werts/Blokos/releases) +- [Compiling it yourself](#compiling) + +## Will this recieve Updates? ## +Possibly, I may port this to +- Nintendo Switch with LIBNX by the DevkitPro team. +- Nintendo 3DS with LIB3DS by the DevkitPro team. +- Xbox ( Original ) with the open source XDK from the community. +- Android/iOS with some SDK's here and there. + +## If I'm programming for BLOKOS, What references can I have? ## +I HIGHLY recommend using this resource to help you +- [Tetris, Tetrimino Guide](https://tetris.fandom.com/wiki/Tetromino) +- [Tetris, Scoring Guide](https://tetris.wiki/Scoring) +- [Tetris, Free Online](https://bit.ly/3z0jaOl) + +# Compiling # +You'll just need a few things. I'm not including ANY libraries +such as __SDL2__, __SDL2 TTF Support__. You'll need to download those from the +[DOWNLOADS](#downloads) section. + +First, Use these commands to Clone, CD and Make the project +```bash +git clone https://github.com/Maddox-Werts/Blokos.git +cd Blokos +make +``` + +And that's it! Make sure you have the said libraries though! +Insinde my **MAKEFILE** I have it so that it automatically +launches the binaries. HOWEVER, If you're on windows, you will +manually need to insert the dll files if you're on windows. + +### DLL FILES REQUIRED TO LAUNCH ON WINDOWS ### +- SDL2.dll +- SDL2_ttf.dll +- SDL2_image.dll +- zlib1.dll +- libpng16-16.dll + + +# Downloads # +### TOOLS ### +- [MINGW](https://sourceforge.net/projects/mingw/) +- [SDL2](http://libsdl.org/download-2.0.php) +- [SDL2 TTF](https://github.com/libsdl-org/SDL_ttf/releases/tag/release-2.0.18) +- [SDL2 Image](https://www.libsdl.org/projects/SDL_image) +- [SDL2 Mixer](http://libsdl.org/projects/SDL_mixer) + +### IDE's ( Up to you ) ### +- [Visual Studio Code](https://code.visualstudio.com/) diff --git a/art/Cell.piskel b/art/Cell.piskel new file mode 100644 index 0000000..de93287 --- /dev/null +++ b/art/Cell.piskel @@ -0,0 +1 @@ +{"modelVersion":2,"piskel":{"name":"Cell","description":"","fps":12,"height":16,"width":16,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKklEQVQ4T2O8ffv2fwYKAOOoAQyjYcAwLMLgxo0blOWFgTfg5MmTFHkBAH65OMAeVamsAAAAAElFTkSuQmCC\"}]}","{\"name\":\"Layer 3\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAbElEQVQ4T2NkoBAwgvTPnz//v5ycHIO2tjbRxj169IjBzMyMEWzA3r17//Py8oIFiDXh1KlT/+EGvHjx4r+EhATRmkGWjBowGgYDnw5AqfDz588Mzs7OkLwAEiA2D4DUgTSDMlNiYiLEAEoAAPi3dBElyQj0AAAAAElFTkSuQmCC\"}]}","{\"name\":\"Layer 2\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK0lEQVQ4T2NkYGD4D8RkA0aoASCaHPB/1ACG0TAAJsLRdEDFMCAnJ4L1AAAJ8x4Bn3F+MgAAAABJRU5ErkJggg==\"}]}"],"hiddenFrames":[""]}} \ No newline at end of file diff --git a/art/Monster.piskel b/art/Monster.piskel new file mode 100644 index 0000000..e5d0868 --- /dev/null +++ b/art/Monster.piskel @@ -0,0 +1 @@ +{"modelVersion":2,"piskel":{"name":"Monster","description":"","fps":6,"height":16,"width":16,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAIElEQVQ4T2MUDmL4z0ABYBw1gGE0DBhGwwCYh4ZBOgAA40kWUQ8UUdcAAAAASUVORK5CYII=\"}]}","{\"name\":\"Layer 4\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAnUlEQVQ4T6VTywqAMAzbwKv4MV78/9Mufox4FSYdVLr0MUWPtkmTtMvp55cj/LylepbU9dA/xlDtKXKBAdgoB0lixY4TLYXLOtVjvxo2tEANqASVmv4sFVK2JOkyIKCVRWRLEWBYMnG2JAkbAU61gvO2okJkr29IzS14YaEq7vu0BSLBoN07iLYxvETLv5eJegss09sE3sTwlEev/QaDJG0Rgk0iTAAAAABJRU5ErkJggg==\"}]}","{\"name\":\"Layer 3\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAv0lEQVQ4T2NkoBAwkqP/PwPDf6BGsF6SDUDWjGHAJ6DJIEE+PAbD1MDUgV3wCqhRDKgJRMO8BOIT4z24ottAzapEakI2GKctx5FcA9JgicNwnAZsAxrgBdWEzAYZBuKDaJA82IDlaLZFotkGkoeJwdTC+HAXzIEakkJEOIDUwtQRFdLIgdYJ1FyOZAmKAelAyZlEuABrLLiihQNM0W4kA9HVgOTgLjAEGnAeqhjEBhkA46MnKGS1JIcBumEUGwAASiwuEVvSVUcAAAAASUVORK5CYII=\"}]}","{\"name\":\"Layer 5\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAATklEQVQ4T2NkoBAwUqifgfoG9P/P/V/IOJlog4lWiOxVZEvIMgDZMOoYgO5vUsKBOi4glBbwuYg+LsDmQpirMFxASgCCDB44L8C8RbELAJM4HBFmjLSWAAAAAElFTkSuQmCC\"}]}","{\"name\":\"Layer 6\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAiElEQVQ4T2NkoBAwUqifYbga8B8IsIUNIxCgi2MIgDQfOnSIwc7OjoFBXp6B4eFDMH1o8WKwGLohKAaga1b+8AFs4d2PH3EaAjcAphmkwS42FmyzMj8/gybQ1VuANIgPchlYHskleF3gA7IZCMAGAAE2bxAOA5BOqO0EwwAWwhTFAqlJexgkZQAJO0sRcMA8UgAAAABJRU5ErkJggg==\"}]}","{\"name\":\"Layer 2\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK0lEQVQ4T2NkYGD4D8RkA0aoASCaHPB/1ACG0TAAJsLRdEDFMCAnJ4L1AAAJ8x4Bn3F+MgAAAABJRU5ErkJggg==\"}]}"],"hiddenFrames":[null]}} \ No newline at end of file diff --git a/art/PrimaxLogo.piskel b/art/PrimaxLogo.piskel new file mode 100644 index 0000000..a11edb4 --- /dev/null +++ b/art/PrimaxLogo.piskel @@ -0,0 +1 @@ +{"modelVersion":2,"piskel":{"name":"PrimaxLogo","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAXUlEQVRYR+2XMQ4AIAjE5P+P1jhgRIkb4FAf4NVOVlrxkeL95gH0YCizeQJEj+vb1u4OkDVuIADAAAYwgAEMYAADGMAABr4yMP/rWW3ghokGQzTEM82Cs/C+vryOB4G4HCFvqmLqAAAAAElFTkSuQmCC\"}]}","{\"name\":\"Layer 6\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAjklEQVRYR+2UsREAIQgEsQ17sA5zm7AOyrAUq/PnAhz+51M0ORIxunVhTHK50uV8CQXova9aq8w5BSeqtfbKDAfIOUspZYsGzBhj54YCIFVVFwC8BW8iHABjMAt/owgHwGs9BO5+DEcAPAR6jMSW8RiAbSFsoLdFPA7w/XcIQAM0QAM0QAM0QAM0QAM08ACUESshdcGWIQAAAABJRU5ErkJggg==\"}]}","{\"name\":\"Layer 2\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAs0lEQVRYR2NkGGDAOMD2M4w6AG8IfIrT/I8cRXyLrlM9xHAaCLKcU1CEgXXiYbCa3/m2/7+/f8NAbUdgdQC65bBQoIUjcDoAl09BjqNmKAxeB7z8/I1Bdf1DFAfeDpT/L87LRdV0gDMEQPGO7AhaWA6yA68D0EtJasY9zGy8DqCFheieGnXAaAiMhsBoCIyGwOAMAVrVfNi6ADjbhCBHoLcHaNGHoHorl1RHjjpgNAQGPAQAUip8IYhG4nEAAAAASUVORK5CYII=\"}]}","{\"name\":\"Layer 5\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAATElEQVRYR2NkGGDAOMD2M4w6YDQEBn8I3Dzk9R+UU9TtttHEsQQNHXAH0LqcIBgCow4YDYHREBgNgdEQGA2B0RAYDYHREBgNgWEfAgC+LgghYMhGZAAAAABJRU5ErkJggg==\"}]}","{\"name\":\"Layer 3\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAsElEQVRYR2NkGGDAOMD2M4w6YDQERkNgNARGQ2BohMCLloT/sDpDomYBI4iPTIPkYGK42MjyyPUPUSEA0nzqwQuwPr85Oxg3pXj8B9HIDgPJwRwFUmumIAHmg9SC2CAxkB70yo9oB4AMg2lGDgGYw2AWoocWeohQ3QEwh6E7CuagAXEAejpBjhKyQgAW5zDNMD6yOLoYLj5ZDqBlq4moRDjqgNEQGA2B0RAYDYFhHQIA1LuqIbKxb6QAAAAASUVORK5CYII=\"}]}","{\"name\":\"Layer 4\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvUlEQVRYR2NkGGDAOMD2M4w6YDQERkNgNARGQ2A0BEZDYDQERkOAqBB40ZLwH9Z0k6hZQJQeYpt6RBkGcsCpBy/AZvrN2cEIcxDMMch8EBskjk8NsuOIdgByCKCHCLJlm1I8/iM7EqQPm4Ng5hHtAPQQAPHNFCTAhoMshbGRQwBZDSwUQY6jSgjAfIXuO2QH4FJDsgNAPoRpAvkAFszINCx9YJOD6YGpIdkBxKZoctQRlQbIMZhYPaMOGA0BAHn9myFundDUAAAAAElFTkSuQmCC\"}]}"],"hiddenFrames":[""]}} \ No newline at end of file diff --git a/bin/README.MD b/bin/README.MD new file mode 100644 index 0000000..a02336f --- /dev/null +++ b/bin/README.MD @@ -0,0 +1,4 @@ +# The BINARY FOLDER # + +This folder will contain the executables you'll need to compile if +you're not downloading from the Releases Tab! \ No newline at end of file diff --git a/inc/InsertSDLIncludesHere.txt b/inc/InsertSDLIncludesHere.txt new file mode 100644 index 0000000..d3e5f44 --- /dev/null +++ b/inc/InsertSDLIncludesHere.txt @@ -0,0 +1,2 @@ +Just toss the downloaded SDL Includes in this folder +(Blokos/inc) \ No newline at end of file diff --git a/lib/InsertSDLLibsHere.txt b/lib/InsertSDLLibsHere.txt new file mode 100644 index 0000000..da02afd --- /dev/null +++ b/lib/InsertSDLLibsHere.txt @@ -0,0 +1,2 @@ +Just toss the downloaded SDL Library ( MINGW i686 ) in this folder +(Blokos/inc) \ No newline at end of file diff --git a/res/fonts/default.ttf b/res/fonts/default.ttf new file mode 100644 index 0000000..f21cfd8 Binary files /dev/null and b/res/fonts/default.ttf differ diff --git a/res/prefs.conf b/res/prefs.conf new file mode 100644 index 0000000..d16df6a --- /dev/null +++ b/res/prefs.conf @@ -0,0 +1,3 @@ +# This file will hold the user's preferences! +width=512 +height=512 \ No newline at end of file diff --git a/res/saves/save.conf b/res/saves/save.conf new file mode 100644 index 0000000..60c9fbd --- /dev/null +++ b/res/saves/save.conf @@ -0,0 +1,5 @@ +# This is a default save file. +# Everything beginning with the # will become a comment +time_alive=0 +high_score=0 +names=none \ No newline at end of file diff --git a/res/sounds/clear.wav b/res/sounds/clear.wav new file mode 100644 index 0000000..5f17977 Binary files /dev/null and b/res/sounds/clear.wav differ diff --git a/res/sounds/die.wav b/res/sounds/die.wav new file mode 100644 index 0000000..10b9a42 Binary files /dev/null and b/res/sounds/die.wav differ diff --git a/res/sounds/entities/anger.wav b/res/sounds/entities/anger.wav new file mode 100644 index 0000000..bea7463 Binary files /dev/null and b/res/sounds/entities/anger.wav differ diff --git a/res/sounds/entities/corrupt.wav b/res/sounds/entities/corrupt.wav new file mode 100644 index 0000000..478f492 Binary files /dev/null and b/res/sounds/entities/corrupt.wav differ diff --git a/res/sounds/entities/kill.wav b/res/sounds/entities/kill.wav new file mode 100644 index 0000000..579200e Binary files /dev/null and b/res/sounds/entities/kill.wav differ diff --git a/res/sounds/entities/move.wav b/res/sounds/entities/move.wav new file mode 100644 index 0000000..64b3fd7 Binary files /dev/null and b/res/sounds/entities/move.wav differ diff --git a/res/sounds/misc/chip.wav b/res/sounds/misc/chip.wav new file mode 100644 index 0000000..9125677 Binary files /dev/null and b/res/sounds/misc/chip.wav differ diff --git a/res/sounds/misc/coin.wav b/res/sounds/misc/coin.wav new file mode 100644 index 0000000..fe9082e Binary files /dev/null and b/res/sounds/misc/coin.wav differ diff --git a/res/sounds/primaxding.wav b/res/sounds/primaxding.wav new file mode 100644 index 0000000..fd3c1c3 Binary files /dev/null and b/res/sounds/primaxding.wav differ diff --git a/res/sounds/tetrimino/drop.wav b/res/sounds/tetrimino/drop.wav new file mode 100644 index 0000000..01dd5c5 Binary files /dev/null and b/res/sounds/tetrimino/drop.wav differ diff --git a/res/sounds/tetrimino/move.wav b/res/sounds/tetrimino/move.wav new file mode 100644 index 0000000..b9fa2c8 Binary files /dev/null and b/res/sounds/tetrimino/move.wav differ diff --git a/res/sounds/tetrimino/slam.wav b/res/sounds/tetrimino/slam.wav new file mode 100644 index 0000000..ec37d20 Binary files /dev/null and b/res/sounds/tetrimino/slam.wav differ diff --git a/res/sprites/cell.png b/res/sprites/cell.png new file mode 100644 index 0000000..d8f8904 Binary files /dev/null and b/res/sprites/cell.png differ diff --git a/res/sprites/monster.png b/res/sprites/monster.png new file mode 100644 index 0000000..f254857 Binary files /dev/null and b/res/sprites/monster.png differ diff --git a/res/sprites/primax.png b/res/sprites/primax.png new file mode 100644 index 0000000..ea0684c Binary files /dev/null and b/res/sprites/primax.png differ diff --git a/res/sprites/title.png b/res/sprites/title.png new file mode 100644 index 0000000..d459234 Binary files /dev/null and b/res/sprites/title.png differ diff --git a/src/app/dtime.c b/src/app/dtime.c new file mode 100644 index 0000000..6dcff24 --- /dev/null +++ b/src/app/dtime.c @@ -0,0 +1,17 @@ +// Files +// --SYSTEM +#include +// --SDL +#include +// --HEADERS +#include "dtime.h" + +// Functions +void updateTime(){ + // Time details + LAST = NOW; + NOW = SDL_GetPerformanceCounter(); + + // Getting DT + deltatime = (float)( (NOW - LAST) * 100 / (float)SDL_GetPerformanceFrequency() ); +} \ No newline at end of file diff --git a/src/app/dtime.h b/src/app/dtime.h new file mode 100644 index 0000000..e98a8c0 --- /dev/null +++ b/src/app/dtime.h @@ -0,0 +1,19 @@ +// Define once +#ifndef H_DTIME +#define H_DTIME + +// Files +// --SYSTEM +#include +// --SDL +#include + +// Variables +Uint64 NOW, LAST; +float deltatime; + +// Functions +void updateTime(); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/features.c b/src/app/features.c new file mode 100644 index 0000000..35b40e5 --- /dev/null +++ b/src/app/features.c @@ -0,0 +1,8 @@ +// Files +// --HEADERS +#include "features.h" + +// Functions +float Lerp(float a, float b, float t){ + return a + t * (b - a); +} \ No newline at end of file diff --git a/src/app/features.h b/src/app/features.h new file mode 100644 index 0000000..24cf724 --- /dev/null +++ b/src/app/features.h @@ -0,0 +1,11 @@ +// Define once +#ifndef H_FEATURES +#define H_FEATURES + +// Files + +// Functions +float Lerp(float a, float b, float t); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/prefs.c b/src/app/prefs.c new file mode 100644 index 0000000..420e373 --- /dev/null +++ b/src/app/prefs.c @@ -0,0 +1,72 @@ +// Files +// --SYSTEM +#include +#include +#include +// --HEADERS +#include "prefs.h" + +// Functions +PX_PrefrenceResult px_ReadPrefs(){ + // Variables + PX_PrefrenceResult holder; + + FILE* file; + char line[512]; + + // Loading the file + file = fopen("res/prefs.conf", "r"); + + // Was the file loaded + if(file == NULL){ + printf("FAILED TO OPEN PREFS FILE!\n"); + } + + // Reading contents + while(fgets(line, 512, file) != NULL){ + if(line[0] == '#'){ // This is a comment + + } + else{ + // Variables + char* args = (char*)malloc(3 * sizeof(int)); + + // Getting stuff + strcpy(args, strtok(line, "=")); + + // Holders + char* name; + char* value; + int time = 0; + + // What was the thing? + while(args != NULL){ + if(time == 0){ + name = args; + } + else{ + value = args; + } + + args = strtok(NULL, "="); + time += 1; + } + + if(strcmp(name, "width") == 0){ + holder.width = atoi(value); + } + else if(strcmp(name, "height") == 0){ + holder.height = atoi(value); + } + + // Clean + free(args); + } + } + + // Cleanup + fclose(file); + + // return + return holder; +} \ No newline at end of file diff --git a/src/app/prefs.h b/src/app/prefs.h new file mode 100644 index 0000000..b7e6b80 --- /dev/null +++ b/src/app/prefs.h @@ -0,0 +1,18 @@ +// Define once +#ifndef H_PREFS +#define H_PREFS + +// Files +// --SYSTEM +// --HEADERS + +// Structures +typedef struct PX_PrefrenceResult{ + int width, height; +} PX_PrefrenceResult; + +// Functions +PX_PrefrenceResult px_ReadPrefs(); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/renderer.c b/src/app/renderer.c new file mode 100644 index 0000000..cee58d9 --- /dev/null +++ b/src/app/renderer.c @@ -0,0 +1,34 @@ +// Files +// --SYSTEM +#include +// --SDL +#include +// --HEADERS +#include "renderer.h" + +// Functions +SDL_Renderer* px_RendererCreate(SDL_Window* window){ + // Making a renderer from the window + SDL_Renderer* renderer = SDL_CreateRenderer( + window, 0, SDL_RENDERER_ACCELERATED + ); + + // Was the renderer made? + if(renderer == NULL){ + printf("Failed to create renderer!\n"); + } + + return renderer; +} +void px_RendererDelete(SDL_Renderer* renderer){ + SDL_DestroyRenderer(renderer); + free(renderer); +} + +void px_RendererClear(SDL_Renderer* renderer){ + SDL_SetRenderDrawColor(renderer, 0,0,0, 1); + SDL_RenderClear(renderer); +} +void px_RendererDisplay(SDL_Renderer* renderer){ + SDL_RenderPresent(renderer); +} \ No newline at end of file diff --git a/src/app/renderer.h b/src/app/renderer.h new file mode 100644 index 0000000..bfd2cd4 --- /dev/null +++ b/src/app/renderer.h @@ -0,0 +1,19 @@ +// Define Once +#ifndef H_RENDERER +#define H_RENDERER + +// Files +// --SYSTEM +// --SDL +#include +// --HEADERS + +// Functions +SDL_Renderer* px_RendererCreate(SDL_Window* window); +void px_RendererDelete(SDL_Renderer* renderer); + +void px_RendererClear(SDL_Renderer* renderer); +void px_RendererDisplay(SDL_Renderer* renderer); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/saves.c b/src/app/saves.c new file mode 100644 index 0000000..0d4a7d9 --- /dev/null +++ b/src/app/saves.c @@ -0,0 +1,154 @@ +// Files +// --SYSTEM +#include +#include +#include +// --HEADER +#include "saves.h" + +// Functions +PX_SaveGame px_saveRead(const char* fileName){ + // Holder + PX_SaveGame saveGame; + + // Variables + FILE* savefile; + char line[512]; + + printf("Reading save from: \n%s\n", fileName); + + // Loading from file + savefile = fopen(fileName, "r"); + + // Was the file opened? + if(savefile == NULL){ + printf("Failed to open %s.\n", fileName); + } + else{ + printf("Successfully read.\n"); + } + + // Loading each line + while(fgets(line, 512, savefile) != NULL){ + // Checking if it's a comment + if(!(line[0] == '#')){ + // Getting the following arguments + //char* saveargs = (char*)malloc(4 * sizeof(int)); + char* saveargs; + + // Split the line + //strcpy(saveargs, line); + saveargs = strtok(line, "="); + + // Temporary Variables + char* savename; + char* savevalue; + + // What are our arguments? + savename = saveargs; + + saveargs = strtok(NULL, "="); + + savevalue = saveargs; + + printf("Loaded info:\n Name: %s\n Value: %s\n\n", savename, savevalue); + + // What was the name? + if(strcmp(savename, "high_score") == 0){ + saveGame.high_score = atoi(savevalue); + printf("Saved high score as: %i\n", saveGame.high_score); + } + if(strcmp(savename, "time_alive") == 0){ + saveGame.time_alive = atoi(savevalue); + printf("Saved time alive as: %i\n", saveGame.time_alive); + } + } + } + + // Cleanup + fclose(savefile); + + // Returning + return saveGame; +} +void px_saveWrite(const char* filename, const char* name, const char* value){ + // DEBUG + printf("Writing to saves..\n"); + + // What's the path? + char* path = (char*)malloc(5 * sizeof(int)); + strcpy(path, "res/saves/"); + strcat(path, filename); + + char* tpath = (char*)malloc(5 * sizeof(int)); + strcpy(tpath, path); + strcat(tpath, ".tmp"); + + printf("Paths: %s, %s\n", path, tpath); + + // DEBUG + printf("Got both save paths..\n"); + + // Getting the file + FILE* savefile = fopen(path, "r"); + FILE* newfile = fopen(tpath, "w"); + + // DEBUG + printf("Loaded both files.\nOG: %i\n NEW: %i\n", (int)(savefile == NULL), (int)(newfile == NULL)); + + // Variables + char line[512]; + + // For each of the lines + while(fgets(line, 512, savefile) != NULL){ + // Is the line a comment? + if(line[0] != '#'){ + // Check the arguments + char* saveargs = (char*)malloc(4 * sizeof(int)); + strcpy(saveargs, strtok(line, "=")); + + // Is this what we want? + // Writing! + char* result = (char*)malloc(4 * sizeof(int)); + + strcpy(result, saveargs); + strcat(result, "="); + if(strcmp(saveargs, name) == 0){ + strcat(result, value); + } + else{ + strcpy(result, line); + strcat(result, "="); + strcat(result, strtok(NULL, "\n")); + } + + printf("Result: %s\n", result); + + // Override line + fputs(result, newfile); + fputc('\n', newfile); + + // Cleanup + free(result); + + // Cleanup + free(saveargs); + } + else{ + // Write to file + fputs(line, newfile); + } + } + + // Closing files + fclose(savefile); + fclose(newfile); + + // Remove the original + remove(path); + + // Override + rename(tpath, path); + + return; +} \ No newline at end of file diff --git a/src/app/saves.h b/src/app/saves.h new file mode 100644 index 0000000..c64bbe4 --- /dev/null +++ b/src/app/saves.h @@ -0,0 +1,21 @@ +// Define once +#ifndef H_SAVES +#define H_SAVES + +// Files +// --SYSTEM +#include +// --HEADERS + +// Structures +typedef struct PX_SaveGame{ + int high_score; + int time_alive; +} PX_SaveGame; + +// Functions +PX_SaveGame px_saveRead(const char* fileName); +void px_saveWrite(const char* filename, const char* name, const char* value); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/sound.c b/src/app/sound.c new file mode 100644 index 0000000..6d2a446 --- /dev/null +++ b/src/app/sound.c @@ -0,0 +1,90 @@ +// Files +// --SYSTEM +#include +// --SDL +#include +#include +// --HEADERS +#include "sound.h" + +// Variables +int totalSounds = 0; + +// Functions +void px_SoundStart(){ + // Values + const Uint16 a_format = AUDIO_S16SYS; + const int a_rate = 22050; + const int a_channels = 2; + const int a_buffers = 4096; + + // Opening a sound + if((Mix_OpenAudio(a_rate, a_format, a_channels, a_buffers))){ + printf("Failed to load Audio Systems!\n"); + } + else{ + printf("Audio Systems started successfuly!\n"); + } +} +void px_SoundPlay(const char* file, int type){ + // Holding + Mix_Chunk* chnk; + + // Freeing previous sound + switch(type){ + case 0: // Background Sounds + Mix_FreeChunk(backgroundsound); + break; + case 1: // Player Sounds + Mix_FreeChunk(playersound); + break; + case 2: // Entity Sounds + Mix_FreeChunk(entitysound); + break; + } + + // Getting the audio file + Mix_Chunk* tchunk = Mix_LoadWAV(file); + if(!tchunk){ + printf("Failed to load Audio File!\n"); + return; + } + + // Setting the current sound + switch(type){ + case 0: // Background Sounds + + backgroundsound = tchunk; + + // Playing the sound + if(!backgroundsound){ + printf("The current sound does not exist!\n"); + return; + } + Mix_PlayChannel(-1, backgroundsound, 0); + + break; + case 1: // Player Sounds + playersound = tchunk; + + // Playing the sound + if(!playersound){ + printf("The current sound does not exist!\n"); + return; + } + Mix_PlayChannel(-1, playersound, 0); + + break; + case 2: // Entity Sounds + entitysound = tchunk; + + // Playing the sound + if(!entitysound){ + printf("The current sound does not exist!\n"); + return; + } + Mix_PlayChannel(-1, entitysound, 0); + + break; + } +} \ No newline at end of file diff --git a/src/app/sound.h b/src/app/sound.h new file mode 100644 index 0000000..4482383 --- /dev/null +++ b/src/app/sound.h @@ -0,0 +1,22 @@ +// Define Once +#ifndef H_SOUND +#define H_SOUND + +// Files +// --SYSTEM +#include +// --SDL2 +#include +#include + +// Variables +Mix_Chunk* backgroundsound; +Mix_Chunk* playersound; +Mix_Chunk* entitysound; + +// Functions +void px_SoundStart(); +void px_SoundPlay(const char* file, int type); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/text.c b/src/app/text.c new file mode 100644 index 0000000..826ebf4 --- /dev/null +++ b/src/app/text.c @@ -0,0 +1,67 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +#include +// --HEADERS +#include "text.h" + +// Functions +PX_Text px_TextCreate(SDL_Renderer* renderer, const char* msg){ + // Starting TTF system + TTF_Init(); + + // Making the holding structure + PX_Text holdtext; + + // Holders/Helpers + SDL_Surface* surf; + SDL_Texture* text; + TTF_Font* font; + + // Was the font opened? + if(!(font = TTF_OpenFont("res/fonts/default.ttf", 16))){ + printf("Could not open font!\n"); + } + + // Getting a color + SDL_Color txt_color = { + 255,255,255, 255 + }; + + // DEBUG + printf("Your message: %s.\n", msg); + + if( !(surf = TTF_RenderText_Solid(font, msg, txt_color)) ){ + printf("Failed to create Render Text\n"); + } + if( !(text = SDL_CreateTextureFromSurface(renderer, surf)) ){ + printf("Failed to create Render Text Texture\n"); + } + + // Assigning stuff + holdtext.font = font; + holdtext.surface = surf; + holdtext.texture = text; + holdtext.width = surf->w; + + // Giving result + return holdtext; +} +void px_TextDraw(SDL_Renderer* renderer, PX_Text text, int x, int y, int w, int h){ + // Holding variable + SDL_Rect rect; + + // Color + SDL_SetRenderDrawColor(renderer, 0,0,0, 1); + + // Giving rect stuff + rect.x = x; rect.y = y; + rect.w = w; rect.h = h; + + // Rendering + SDL_RenderDrawRect(renderer, &rect); + SDL_RenderCopy(renderer, text.texture, NULL, &rect); +} \ No newline at end of file diff --git a/src/app/text.h b/src/app/text.h new file mode 100644 index 0000000..81d52bd --- /dev/null +++ b/src/app/text.h @@ -0,0 +1,26 @@ +// Define once +#ifndef H_TEXT +#define H_TEXT + +// Files +// --SYSTEM +#include +// --SDL +#include +#include + +// Structures +typedef struct PX_Text{ + TTF_Font* font; + SDL_Surface* surface; + SDL_Texture* texture; + + int width; +} PX_Text; + +// Functions +PX_Text px_TextCreate(SDL_Renderer* renderer, const char* msg); +void px_TextDraw(SDL_Renderer* renderer, PX_Text text, int x, int y, int w, int h); + +// End if +#endif \ No newline at end of file diff --git a/src/app/texture.c b/src/app/texture.c new file mode 100644 index 0000000..c31f3a2 --- /dev/null +++ b/src/app/texture.c @@ -0,0 +1,31 @@ +// Files +// --SYSTEM +#include +// --SDL +#include +#include +// --HEADERS +#include "texture.h" + +// Functions +SDL_Texture* px_TextureCreate(SDL_Renderer* renderer, const char* file){ + // Helpers + SDL_Texture* result; + SDL_Surface* texsurf; + + // Was the surface loaded? + if(!(texsurf = IMG_Load(file))){ + printf("Failed to load Texture Image: %s.\n", file); + } + + // Converting surface to texture + if(!(result = SDL_CreateTextureFromSurface(renderer, texsurf))){ + printf("Failed to create texture from surface!\n"); + } + + // Cleanup + SDL_FreeSurface(texsurf); + + // Returning Result + return result; +} \ No newline at end of file diff --git a/src/app/texture.h b/src/app/texture.h new file mode 100644 index 0000000..1cb53b7 --- /dev/null +++ b/src/app/texture.h @@ -0,0 +1,14 @@ +// Defining +#ifndef H_TEXTURE +#define H_TEXTURE + +// Files +// --SYSTEM +// --SDL +#include + +// Functions +SDL_Texture* px_TextureCreate(SDL_Renderer* renderer, const char* file); + +// End definition +#endif \ No newline at end of file diff --git a/src/app/window.c b/src/app/window.c new file mode 100644 index 0000000..97f8ccf --- /dev/null +++ b/src/app/window.c @@ -0,0 +1,67 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +// --HEADERS +#include "window.h" + +/* + -- THIS IS FOR THE WINDOW! -- +*/ + +// Functions +PX_Window px_WindowCreate(const char* title, int width, int height){ + // Starting some things + SDL_Init(SDL_INIT_VIDEO); + SDL_Init(SDL_INIT_AUDIO); + + // Making the holding structure + PX_Window window; + + // Creating a window + window.window = SDL_CreateWindow( + title, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_SHOWN + ); + + // Was the window created? + if(window.window == NULL){ + printf("Failed to create window!\n"); + } + + // Setting others + window.width = width; + window.height = height; + window.opened = true; + + // Returning Window + return window; +} +void px_WindowDelete(PX_Window* window){ + SDL_DestroyWindow(window->window); + free(window); +} + +void px_WindowUpdate(PX_Window* window){ + // Making an event holder + SDL_Event ev; + + // Polling through events + while(SDL_PollEvent(&ev)){ + // Going through all types + switch(ev.type){ + // Pressing the X button + case SDL_QUIT: + window->opened = false; + break; + // Pressing Escape + case SDL_KEYDOWN: + if(ev.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { window->opened = false; } + break; + } + } +} \ No newline at end of file diff --git a/src/app/window.h b/src/app/window.h new file mode 100644 index 0000000..3643bd1 --- /dev/null +++ b/src/app/window.h @@ -0,0 +1,26 @@ +// Define once +#ifndef H_WINDOW +#define H_WINDOW + +// Files +// --SYSTEM +#include +// --SDL +#include +// --HEADERS + +// Structures +typedef struct PX_Window{ + SDL_Window* window; + int width, height; + bool opened; +} PX_Window; + +// Functions +PX_Window px_WindowCreate(const char* title, int width, int height); +void px_WindowDelete(PX_Window* window); + +void px_WindowUpdate(PX_Window* window); + +// End definition +#endif \ No newline at end of file diff --git a/src/gme/monster.c b/src/gme/monster.c new file mode 100644 index 0000000..7541742 --- /dev/null +++ b/src/gme/monster.c @@ -0,0 +1,250 @@ +// Files +// --SYSTEM +#include +#include +#include +// --SDL +#include +#include +// --HEADERS +#include "../gme/scene.h" +#include "../app/sound.h" +#include "../app/dtime.h" +#include "monster.h" + +// Constants +#define FALLT 4 +#define RESPAWNT 213 +#define FALLSLICE 120.0f/1000.0f + +// Variables +bool finishedAnger = false; +float ftime = 0; +int standstill = 0; + +// Functions +// --HELPER +void px_MACTIVATE(PX_Monster* monster){ + + // Adding to time + if(ftime > RESPAWNT){ + ftime = 0; + standstill = false; + monster->active = true; + monster->x = 3; + monster->y = 0; + + // Making the sounds + px_SoundPlay("res/sounds/entities/anger.wav", 2); + } + else{ + ftime += deltatime * FALLSLICE; + } +} + +void px_MFALL(PX_Monster* monster, PX_Scene* scene){ + // Grounded? + if(monster->grounded) {return;} + + // Falling + if(ftime > FALLT){ + monster->y += 1; + ftime = 0; + } + // Counting + else{ + ftime += deltatime * FALLSLICE; + } + + // Are we below the grid? + if(monster->y > GRIDY){ + monster->active = false; + return; + } +} +void px_MSTRIDE(PX_Monster* monster, PX_Scene* scene){ + // Can we even move? + if(ftime < FALLT){ + return; + } + + // Getting a random direction + srand(time(NULL)); + + // Helpers + int randec, direction; + + // Getting the random range + randec = rand() % 100; + + // Here's whats gonna happen: + /* + IF: The range is between 0-40 + THEN: Move LEFT + + IF: the range is between 40-60 + THEN: Stay put + + IF: the range is between 60-100 + THEN: Move RIGHT + */ + + if(randec < 40){ + direction = -1; + } + else if(40 <= randec && randec <= 60){ + return; + } + else if(60 < randec && randec < 100){ + direction = +1; + } + else{ + printf("What did you do? It's broken?\n"); + } + + // Can we move in the direction we want? + if(monster->x + direction < 0){ + monster->x = GRIDX - 1; + } + else if(monster->x + direction > GRIDX - 1){ + monster->x = 1; + } + + // Will we end up moving into a tile? + int nexttile = px_SceneGet(scene, monster->x + direction, monster->y); + + if(nexttile != 0) {standstill += 1; return;} + else {standstill = 0;} + + monster->x += direction; + + // Sounds + px_SoundPlay("res/sounds/entities/move.wav", 2); +} +void px_MKILL(PX_Monster* monster, PX_Scene* scene){ + /* + We won't kill the monster if he is overriden by a block + that is already placed + =========================== + */ + + // What's our position in the grid? + int ccell = px_SceneGet(scene, monster->x, monster->y); + + // Are we in something.. + if(ccell == -1){ + // Can we move above + if(px_SceneGet(scene, monster->x, monster->y - 1) == 0){ + monster->y -= 1; + } + else{ + // Kill + px_SoundPlay("res/sounds/entities/kill.wav", 2); + monster->active = false; + } + } + + // Are we in a standstill.. + if(standstill > 4){ + // Kill + px_SoundPlay("res/sounds/entities/kill.wav", 2); + monster->active = false; + } +} +void px_MGCHECK(PX_Monster* monster, PX_Scene* scene){ + // Are we on the floor? + if(monster->y + 2 > GRIDY){ + monster->grounded = true; + return; + } + + // What's the tile below us? + int below = px_SceneGet(scene, monster->x, monster->y + 1); + + // Is it ground? + monster->grounded = below != 0; +} +void px_MCORRUPT(PX_Monster* monster, PX_Scene* scene){ + // Grounded? + if(!monster->grounded) {return;} + + // Corrupt when it's time + if(ftime > FALLT){ + ftime = 0; + + if(monster->y + 2 < GRIDY){ + px_ScenePlot(scene, monster->x, monster->y + 1, 0); + + // Playing a sound + px_SoundPlay("res/sounds/entities/corrupt.wav", 2); + + // Should we stand still? + int shouldStand = rand() % 50; + + if(shouldStand > 10){ + standstill = 0; + } + } + } + else{ + ftime += deltatime * FALLSLICE; + } +} + +// --HEADER +PX_Monster px_MonsterCreate(SDL_Renderer* renderer){ + // Holding + PX_Monster monster; + + // Setting variables + monster.grounded = false; + monster.active = false; + monster.x = 3; + monster.y = 0; + + // Creating the texture + monster_tex = px_TextureCreate(renderer, "res/sprites/monster.png"); + + // Returning monster + return monster; +} +void px_MonsterUpdate(PX_Monster* monster, PX_Scene* scene){ + + // Active? + if(!monster->active) {px_MACTIVATE(monster); return;} + + // Checks + px_MGCHECK(monster, scene); + + // Physics + px_MSTRIDE(monster, scene); + px_MFALL(monster, scene); + + // Effects + px_MCORRUPT(monster, scene); + + // Checks + px_MKILL(monster, scene); +} +void px_MosnterDraw(SDL_Renderer* renderer, PX_Scene* scene, PX_Monster* monster){ + // Active? + if(!monster->active) {return;} + + // Making shapes + SDL_Rect rect; + + // Constants + const int _xgrid = scene->width / GRIDX; + const int _ygrid = scene->height / GRIDY; + + // Updating positional values + rect.x = monster->x * _xgrid; rect.y = monster->y * _ygrid; + rect.w = _xgrid; rect.h = _ygrid; + + // Set Color + SDL_SetRenderDrawColor(renderer, 255,255,255, 1); + SDL_RenderFillRect(renderer, &rect); + + // Drawing texture + SDL_RenderCopy(renderer, monster_tex, NULL, &rect); +} \ No newline at end of file diff --git a/src/gme/monster.h b/src/gme/monster.h new file mode 100644 index 0000000..70fc917 --- /dev/null +++ b/src/gme/monster.h @@ -0,0 +1,32 @@ +// Define once +#ifndef H_MONSTER +#define H_MONSTER + +// Files +// --SYSTEM +#include +// --SDL +#include +#include +// --HEADERS +#include "../gme/scene.h" +#include "../app/texture.h" +#include "../app/dtime.h" + +// Structures +typedef struct PX_Monster{ + int x; int y; + bool grounded; + bool active; +} PX_Monster; + +// Variables +SDL_Texture* monster_tex; + +// Functions +PX_Monster px_MonsterCreate(SDL_Renderer* renderer); +void px_MonsterUpdate(PX_Monster* monster, PX_Scene* scene); +void px_MosnterDraw(SDL_Renderer* renderer, PX_Scene* scene, PX_Monster* monster); + +// End definition +#endif \ No newline at end of file diff --git a/src/gme/scene.c b/src/gme/scene.c new file mode 100644 index 0000000..8ff2efc --- /dev/null +++ b/src/gme/scene.c @@ -0,0 +1,191 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +#include +// --HEADERS +#include "scene.h" +#include "../app/texture.h" +#include "../app/sound.h" +#include "../app/dtime.h" + +// Functions + +// Variables +int redRows = 0; +float redTime = 0; + +// --HEADER +PX_Scene px_SceneCreate(SDL_Renderer* renderer, int width, int height){ + // Making the structure + PX_Scene scene = { + { + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, + }, + width, height, + 0 + }; + + // Setting something Important + gameOver = false; + redRows = 0; + redTime = 0; + + // Loading textures + celltex = px_TextureCreate(renderer, "res/sprites/cell.png"); + SDL_SetTextureBlendMode(celltex, SDL_BLENDMODE_BLEND); + + return scene; +} +void px_SceneDelete(PX_Scene* scene){ + free(scene); +} + +void px_ScenePlot(PX_Scene* scene, int x, int y, int value){ + // Plotting based on thing + scene->matricies[y*GRIDX+x] = value; +} +int px_SceneGet(PX_Scene* scene, int x, int y){ + return scene->matricies[y*GRIDX+x]; +} +void px_SceneDraw(PX_Scene* scene, SDL_Renderer* renderer){ + // Drawing our scene every x&y coords + for(int y = 0; y < GRIDY; y++){ + // For the awesomeness! + int cellsfilled = 0; + + for(int x = 0; x < GRIDX; x++){ + // Helpers + bool filled; + + // Color + SDL_SetRenderDrawColor(renderer, 134,134,134, 1); + + // Game over? + if(gameOver){ + if(y <= redRows){ + filled = true; + SDL_SetRenderDrawColor(renderer, 255, 55, 55, 1); + SDL_SetTextureColorMod(celltex, 255, 55, 55); + } + else{ + SDL_SetRenderDrawColor(renderer, 134,134,134, 1); + SDL_SetTextureColorMod(celltex, 134, 134, 134); + } + + if(redTime >= 240.0f){ + redTime = 0; + redRows += 1; + } + else{ + redTime += deltatime * (120.0f/1000.0f); + } + } + else{ + // Setting color + // What type of cell is it? + if(scene->matricies[y*GRIDX+x] == -1){ + SDL_SetTextureColorMod(celltex, 175,200,175); + cellsfilled += 1; + filled = true; + } + else if(scene->matricies[y*GRIDX+x] != 0){ + SDL_SetTextureColorMod(celltex, 225,225,255); + filled = true; + } + else{ + SDL_SetTextureColorMod(celltex, 100,100,100); + filled = false; + } + } + + // Getting the size difference from window + const int _xgrid = scene->width / GRIDX; + const int _ygrid = scene->height / GRIDY; + + // Making the rectangle + SDL_Rect rect; + + // Placing rect + rect.x = x * _xgrid; + rect.y = y * _ygrid; + rect.w = _xgrid; rect.h = _ygrid; + + // Drawing rect + if(filled){ + SDL_RenderFillRect(renderer, &rect); + SDL_RenderCopy(renderer, celltex, NULL, &rect); + } + else{ + SDL_RenderDrawRect(renderer, &rect); + } + + // Clear board! + // -- USELESS CODE! + // Making it so that it'll be able + // to hold all prior cells + + // scene->matricies[y*GRIDX+x] = 0; + } + + // Were all the cells filled? + if(cellsfilled >= GRIDX){ + // Playing the sound + px_SoundPlay("res/sounds/clear.wav", 0); + + // Clearing rows + for(int cy = y; cy > 0; cy--){ + for(int x = 0; x < GRIDX; x++){ + scene->matricies[cy*GRIDX+x] = scene->matricies[(cy-1)*GRIDX+x]; + } + } + + // The effect + for(int ts = 0; ts < 3; ts++){ + for(int x = 0; x < GRIDX; x++){ + // Effect Color + SDL_SetRenderDrawColor(renderer, 255, 255, 0, 1); + + // Getting the size difference from window + const int _xgrid = scene->width / GRIDX; + const int _ygrid = scene->height / GRIDY; + + // Making the rectangle + SDL_Rect rect; + + // Placing rect + rect.x = x * _xgrid; + rect.y = y * _ygrid; + rect.w = _xgrid; rect.h = _ygrid; + + SDL_RenderFillRect(renderer, &rect); + + // Drawing cool things + SDL_RenderPresent(renderer); + SDL_Delay(20); + } + } + + // Points? + scene->score += 100; + printf("New Score: %i\n", scene->score); + } + } +} \ No newline at end of file diff --git a/src/gme/scene.h b/src/gme/scene.h new file mode 100644 index 0000000..726d003 --- /dev/null +++ b/src/gme/scene.h @@ -0,0 +1,44 @@ +// Define once +#ifndef H_SCENE +#define H_SCENE + +// Files +// --SYSTEM +// --SDL +#include +#include +#include +// --HEADERS +#include "tetriminos.h" +#include "../app/sound.h" + +/* + For this, The scene will be a + 9x16 grid = 144 +*/ + +// CONSTANTS +#define GRIDX 9 +#define GRIDY 16 + +// Structure +typedef struct PX_Scene{ + int matricies[144]; + int width, height; + int score; +} PX_Scene; + +// Variables +SDL_Texture* celltex; +bool gameOver; + +// Functions +PX_Scene px_SceneCreate(SDL_Renderer* renderer, int width, int height); +void px_SceneDelete(PX_Scene* scene); + +void px_ScenePlot(PX_Scene* scene, int x, int y, int value); +int px_SceneGet(PX_Scene* scene, int x, int y); +void px_SceneDraw(PX_Scene* scene, SDL_Renderer* renderer); + +// End definition +#endif \ No newline at end of file diff --git a/src/gme/tetrimino.c b/src/gme/tetrimino.c new file mode 100644 index 0000000..0d8cb53 --- /dev/null +++ b/src/gme/tetrimino.c @@ -0,0 +1,423 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +#include +// --HEADERS +#include "tetrimino.h" +#include "../app/sound.h" +#include "../app/dtime.h" + +// CONSTANTS +#define FTIME 120.0f/1000.0f + +// Functions +// --HELPERS +/* + Helper Function Format: + void px_T[FUNCTION NAME](PX_Tetrimino* tetrimino); + + Also no, I'm not going to use TYPEDEF for my structures. + I do NOT know how to use those haha +*/ +// ----DRAWING +// ----COLLISION +bool px_TCOLLIDING(PX_Tetrimino* tetrimino, PX_Scene* scene){ + for(int y = 0; y < 4; y++){ + // Lets be sure we're not on the ground. + if(tetrimino->y + y + 1 > GRIDY || tetrimino->y + y - 1 < 0){ + break; + } + + // All X's + for(int x = 0; x < 4; x++){ + // Current tile: + int ctile = px_SceneGet(scene, tetrimino->x + x, tetrimino->y + y); + + // Is this tile VALID + if(ctile == tetrimino->type + 1){ + // Get the thing below us: + int belowTile = px_SceneGet(scene, tetrimino->x + x, tetrimino->y + y + 1); + + // Is something below us? + if(belowTile != 0 && belowTile != tetrimino->type + 1){ + return true; + } + } + } + } + + // Not a success + return false; +} +bool px_TOVEREDGE(PX_Tetrimino* tetrimino, PX_Scene* scene, int xoffset, int yoffset){ + int width, start; + + width = 0; start = 4; + + // What is our width? + for(int y = 0; y < 4; y++){ + for(int x = 0; x < 4; x++){ + // What's our cell? + int ccell = px_SceneGet(scene, tetrimino->x + x, tetrimino->y + y); + + // Is our cell valid + if(ccell == tetrimino->type + 1){ + // Setting stuff + if(x < start) { start = x; } + if(width < x) { width = x; } + } + } + } + + // Giving the piece its info + tetrimino->width = width; + + // Can we move? + return tetrimino->x + start + xoffset < 0 + || tetrimino->x + width + (xoffset + 1) > GRIDX; +} +// ----PHYSICS +void px_TFALL(PX_Tetrimino* tetrimino){ + if(tetrimino->ft > 4){ + tetrimino->y += 1; + tetrimino->ft = 0; + } + else{ + tetrimino->ft += FTIME * deltatime; + } +} +void px_TBORDER(PX_Tetrimino* tetrimino, PX_Scene* scene){ + if(tetrimino->y >= GRIDY - 2){ + + // Playing the sound + if(!tetrimino->dropping){ + px_SoundPlay("res/sounds/tetrimino/drop.wav", 1); + } + + tetrimino->still = true; + } +} +void px_TDRAW(PX_Tetrimino* tetrimino, PX_Scene* scene, int x, int y, int spriteval){ + // Placeholding someting? + const int tetdrawtype = tetrimino->type + 1; + int width = 0; + + // What is our width? + switch(tetrimino->type){ + case 0: + width = 4; break; + case 1: + case 2: + case 4: + case 5: + case 6: + case 7: + width = 3; break; + case 3: + width = 2; break; + } + + // This is the value of the cell we're trying to get + int cellv = px_SceneGet(scene, x+tetrimino->x, y+tetrimino->y); + + if( cellv == 0 + || cellv == tetdrawtype){ + // Are we still? + if(tetrimino->still){ + px_ScenePlot(scene, x + tetrimino->x, y + tetrimino->y, spriteval * -1); + } + else{ + px_ScenePlot(scene, x + tetrimino->x, y + tetrimino->y, spriteval * tetdrawtype); + } + } + + // Are the cells above avalible? + if((tetrimino->y - 1) * GRIDY + tetrimino->x > 0){ + // Clearing cells above + for(int c = 0; c < width; c++){ + px_ScenePlot(scene, c + tetrimino->x, tetrimino->y - 1, 0); + } + } +} +void px_TCHECKOTHER(PX_Tetrimino* tetrimino, PX_Scene* scene){ + // This is so that we're able to detect if we're colliding with another block + // Only the top part will be detected now + /* + -- NEW SYSTEM OF COLLISION! + This system will account for + rotations + */ + + if(px_TCOLLIDING(tetrimino, scene)){ + tetrimino->still = true; + // The sound + if(!tetrimino->dropping){ + px_SoundPlay("res/sounds/tetrimino/drop.wav", 1); + } + + // Are we gamed over? + if(tetrimino->y <= 2){ + tet_gameOver = true; + } + } +} + +// --REGULARS +PX_Tetrimino px_TetriminoCreate(){ + // Making stuff + PX_Tetrimino tetrimino; + + // Assigning Variables + tetrimino.x = 3; + tetrimino.y = 1; + tetrimino.width = 0; + tetrimino.ft = 0; + tetrimino.type = 1; + + tetrimino.still = false; + tetrimino.dropping = false; + + tet_gameOver = false; + + // Giving back tetrimino + return tetrimino; +} +void px_TetriminoDelete(PX_Tetrimino* tetrimino){ + free(tetrimino); +} +void px_TetriminoReset(PX_Tetrimino* tetrimino){ + tetrimino->still = false; + tetrimino->dropping = false; + tetrimino->y = 0; + tetrimino->x = 3; + tetrimino->ft = 0; + tetrimino->type += 1; + tetrimino->rotation = 0; + + if(tetrimino->type >= 7) {tetrimino->type = 1;} +} +void px_TetriminoUpdate(PX_Tetrimino* tetrimino, PX_Scene* scene){ + // Are we static? + if(tetrimino->still) {printf("STILL\n"); return;} + + // Physics + px_TFALL(tetrimino); + px_TCHECKOTHER(tetrimino, scene); + + // Checks + px_TBORDER(tetrimino, scene); +} +void px_TetriminoDraw(PX_Tetrimino* tetrimino, PX_Scene* scene){ + /* + Rotations, are complicated. + Let's use a little cheat to get through it! + */ + + // Going through X and Y + for (int wy = 0; wy < 4; wy ++){ + for (int wx = 0; wx < 4; wx ++){ + // Sorting out the rotation stuff + int x,y; + + // Flipping? + switch(tetrimino->rotation){ + case 0: // Up + x = wx; + y = wy; + break; + case 1: // Right + x = wy; + y = 2 - wx; + break; + case 2: // Down + x = 2 - wx; + y = 2 - wy; + break; + case 3: // Left + x = 2 - wy; + y = wx; + break; + } + + // Going through each type + switch(tetrimino->type){ + // The I piece + case 0: + px_TDRAW(tetrimino, scene, wx,wy, te_I[y*4+x]); + break; + + // The J piece + case 1: + px_TDRAW(tetrimino, scene, wx,wy, te_J[y*4+x]); + break; + + // The L piece + case 2: + px_TDRAW(tetrimino, scene, wx,wy, te_L[y*4+x]); + break; + + // The O piece + case 3: + px_TDRAW(tetrimino, scene, wx,wy, te_O[y*4+x]); + break; + + // The S piece + case 4: + px_TDRAW(tetrimino, scene, wx,wy, te_S[y*4+x]); + break; + + // The T piece + case 5: + px_TDRAW(tetrimino, scene, wx,wy, te_T[y*4+x]); + break; + + // The Z piece + case 6: + px_TDRAW(tetrimino, scene, wx,wy, te_Z[y*4+x]); + break; + + default: + break; + } + } + } +} +void px_TetriminoMove(PX_Tetrimino* tetrimino, PX_Scene* scene, int x, int y){ + // Moving the wanted tetrimino + // Appropriate? + if(px_TOVEREDGE(tetrimino, scene, x, 0)) {return;} + + // Moving + tetrimino->x += x; + + // Playing a sound + px_SoundPlay("res/sounds/tetrimino/move.wav", 1); + + // Clearing cells on the side it was moving away from + // If this doesn't happen, GLITCHES happen.. + if(x > 0){ // Moving Right + for(int y = 0; y < 4; y++){ + // Getting the point + int cellv = px_SceneGet(scene, tetrimino->x - 1, tetrimino->y + y - 1); + + if(cellv == tetrimino->type + 1){ + px_ScenePlot(scene, tetrimino->x - 1, tetrimino->y + y - 1, 0); + } + } + } + else if(x < 0){ // Moving Left + // Are we going to cause a index out of range crash? + if((tetrimino->y - 1) * GRIDY + tetrimino->x > 0){ + for(int y = 0; y < 4; y++){ + // Getting the point + int cellv = px_SceneGet(scene, tetrimino->x + tetrimino->width + 1, tetrimino->y + y); + + if(cellv == tetrimino->type + 1){ + px_ScenePlot(scene, tetrimino->x + tetrimino->width + 1, tetrimino->y + y, 0); + } + } + } + } +} +void px_TetriminoDrop(PX_Tetrimino* tetrimino, PX_Scene* scene){ + // Dropping the tetrimino + // These are our helpers + bool didDrop = false; + int height, width, xoff; + + // Whats our height? + height = tetrimino->y + 1; + + // Whats our width? + switch(tetrimino->type){ + case 1: + case 2: + case 5: + width = 3; xoff = 0; break; + case 4: + case 3: + width = 2; xoff = 0; break; + case 6: + width = 2; xoff = 1; break; + } + + // Avalible points? + if(tetrimino->y * GRIDY + tetrimino->x > 0){ + // Resetting surrounding graphics + for(int y = 0; y < 4; y++){ + for(int x = 0; x < 4; x++){ + if(px_SceneGet(scene, tetrimino->x + x, tetrimino->y + y - 1) == tetrimino->type + 1){ + px_ScenePlot(scene, tetrimino->x + x, tetrimino->y + y - 1, 0); + } + } + } + } + + // Dropping! + while(!didDrop && !tetrimino->still){ + // Going through the width + for(int x = 0; x < width; x++){ + // Are we on the ground? + if(height + 2 > GRIDY){ + didDrop = true; + break; + } + else{ + // Checking others + if(px_TCOLLIDING(tetrimino, scene)){ + didDrop = true; + break; + } + } + } + + // Did we escape? + if(didDrop){ + // Playing the sound + px_SoundPlay("res/sounds/tetrimino/slam.wav", 1); + + break; + } + // KEEP FALLING! + else{ + // Falling + tetrimino->y += 1; + height = tetrimino->y + 1; + + // Drawing so it's consistent + px_TetriminoDraw(tetrimino, scene); + } + } + + // We're still + // So play the cool sound! + tetrimino->dropping = true; + // Drop imidiatly. + tetrimino->ft = 4; + // Just to buffer + SDL_Delay(25); +} +void px_TetriminoRotate(PX_Tetrimino* tetrimino, PX_Scene* scene, int direction){ + // Dumb types + if(tetrimino->type == 3) {return;} + + // Are we avalible to turn? + if(px_TOVEREDGE(tetrimino, scene, direction, 0)) {return;} + + // Rotating + tetrimino->rotation += direction; + + // Clamping + if(tetrimino->rotation < 0){ + tetrimino->rotation = 3; + } + if(tetrimino->rotation > 3){ + tetrimino->rotation = 0; + } + + // New rotation? + printf("Rotation: %i\n", tetrimino->rotation); +} \ No newline at end of file diff --git a/src/gme/tetrimino.h b/src/gme/tetrimino.h new file mode 100644 index 0000000..609d9e5 --- /dev/null +++ b/src/gme/tetrimino.h @@ -0,0 +1,45 @@ +// Define once +#ifndef H_TETRIMINO +#define H_TETRIMINO + +// Files +// --SYSTEM +#include +// --SDL +#include +#include +// --HEADERS +#include "scene.h" +#include "../app/sound.h" + +// Structures +typedef struct PX_Tetrimino{ + // Variables + int x,y; + int width; + int type; + int rotation; + + // Cases + bool still, dropping; + + // Timers + float ft; +} PX_Tetrimino; + +// Variables +bool tet_gameOver; + +// Functions +PX_Tetrimino px_TetriminoCreate(); +void px_TetriminoDelete(PX_Tetrimino* tetrimino); + +void px_TetriminoUpdate(PX_Tetrimino* tetrimino, PX_Scene* scene); +void px_TetriminoDraw(PX_Tetrimino* tetrimino, PX_Scene* scene); +void px_TetriminoReset(PX_Tetrimino* tetrimino); +void px_TetriminoMove(PX_Tetrimino* tetrimino, PX_Scene* scene, int x, int y); +void px_TetriminoDrop(PX_Tetrimino* tetrimino, PX_Scene* scene); +void px_TetriminoRotate(PX_Tetrimino* tetrimino, PX_Scene* scene, int direction); + +// End definition +#endif \ No newline at end of file diff --git a/src/gme/tetriminos.c b/src/gme/tetriminos.c new file mode 100644 index 0000000..b30a245 --- /dev/null +++ b/src/gme/tetriminos.c @@ -0,0 +1,62 @@ +// File +#include "tetriminos.h" + +/* + -- This is a zero'd out thing -- + + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0 +*/ + +// Pieces +int te_I[16] = { + 0,0,0,0, + 1,1,1,1, + 0,0,0,0, + 0,0,0,0 +}; + +// -- THE J PIECE +int te_J[16] = { + 1,0,0,0, + 1,1,1,0, + 0,0,0,0, + 0,0,0,0 +}; + +int te_L[16] = { + 0,0,1,0, + 1,1,1,0, + 0,0,0,0, + 0,0,0,0 +}; + +int te_O[16] = { + 1,1,0,0, + 1,1,0,0, + 0,0,0,0, + 0,0,0,0 +}; + +int te_S[16] = { + 0,1,1,0, + 1,1,0,0, + 0,0,0,0, + 0,0,0,0 +}; + +int te_T[16] = { + 0,1,0,0, + 1,1,1,0, + 0,0,0,0, + 0,0,0,0 +}; + +int te_Z[16] = { + 1,1,0,0, + 0,1,1,0, + 0,0,0,0, + 0,0,0,0 +}; \ No newline at end of file diff --git a/src/gme/tetriminos.h b/src/gme/tetriminos.h new file mode 100644 index 0000000..4ab958d --- /dev/null +++ b/src/gme/tetriminos.h @@ -0,0 +1,30 @@ +// Define once +#ifndef H_TETRIMINOS +#define H_TETRIMINOS + +/* + + This file will hold all the tetrminos + the player will have at store to use! + + Each shape will be "Referenced" + as a 4x4 grid. So 16 cells. + In the "Scene", it will be a BOOLEAN + MATRIX. So 1 represents something, + and 0 represents nothing! + + All of these will begin with: + const int te_ + +*/ + +int te_I[16]; +int te_J[16]; +int te_L[16]; +int te_O[16]; +int te_S[16]; +int te_T[16]; +int te_Z[16]; + +// End definition +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..90e97ec --- /dev/null +++ b/src/main.c @@ -0,0 +1,127 @@ +/* + -- BLOKOS -- + A simple Tetris Re-Make for my Computer Science + class In May of 2022. I'm going to choose the + C language, because it makes the Most sense to me. + My code may be a little sloppy, so if there's anything horrible, + feel free to let me know! +*/ + +// For SDL(WINDOWS) +#define SDL_MAIN_HANDLED + +// Files +// --SYSTEM +#include +#include +// --HEADERS +#include "app/window.h" +#include "app/renderer.h" +#include "gme/scene.h" +#include "gme/tetrimino.h" +// --BASE +#include "app/dtime.h" +#include "app/prefs.h" +#include "app/saves.h" +// --SCREENS +#include "scn/gameplay.h" +#include "scn/mainmenu.h" +#include "scn/splash.h" + +// Variables +int cscrn; +bool rtt; + +// Functions +void switchscrn(){ + // Getting key state + const Uint8* ks = SDL_GetKeyboardState(NULL); + + // If Space is pressed + if(ks[SDL_SCANCODE_SPACE] && px_mcanstart){ + rtt = true; + } + else if(!(ks[SDL_SCANCODE_SPACE]) && rtt){ + if(cscrn == 0) { blk_MMClean(); } + cscrn += 1; + rtt = false; + } +} + +// Entry Point +int main(int argc, char* argv[]){ + // This is our starting point + // Prefrences + PX_PrefrenceResult prefs = px_ReadPrefs(); + + // Loading save game + PX_SaveGame saveGame = px_saveRead("res/saves/save.conf"); + + // Creating a window + PX_Window window = px_WindowCreate("BLOKOS", prefs.width, prefs.height); + SDL_Renderer* renderer = px_RendererCreate(window.window); + + // Screen state + cscrn = -1; rtt = false; + + // Starting the Sound System + px_SoundStart(); + + // Making the game screen + px_SSstart(renderer, window.width, window.height); + blk_MMCreate(renderer); + blk_GameStart(renderer, &saveGame); + + // Game Loop + while(window.opened){ + // Update window + px_WindowUpdate(&window); + + // Clear screen + px_RendererClear(renderer); + + // Getting Delta Time + updateTime(); + + // Switching between screens + switch(cscrn){ + case -1: + // Game code.. + px_SSupdate(); + if(px_ssready) {cscrn = 0; px_SSclean();} + // Render code.. + px_SSdraw(renderer, window.width, window.height); + + + break; + + case 0: + // Game code.. + blk_MMUpdate(); + switchscrn(); + // Render code.. + blk_MMDraw(renderer); + // End screen + break; + case 1: + // Game code.. + blk_GameUpdate(&saveGame); + // Render code.. + blk_GameDraw(renderer); + // End screen + break; + } + + // Display screen + px_RendererDisplay(renderer); + } + + // Cleanup + px_TetriminoDelete(&tetrimino); + px_SceneDelete(&scene); + px_RendererDelete(renderer); + px_WindowDelete(&window); + + // Exiting the app + return 0; +} \ No newline at end of file diff --git a/src/scn/gameplay.c b/src/scn/gameplay.c new file mode 100644 index 0000000..f511fe3 --- /dev/null +++ b/src/scn/gameplay.c @@ -0,0 +1,170 @@ +// Files +// --SYSTEM +#include +#include +#include +// --SDL +#include +// --HEADERS +#include "gameplay.h" +#include "../app/saves.h" +#include "../gme/monster.h" + +// Variables +PX_Monster monster; +bool didWrite = false; + +// Functions +// --HELPER +void game_MoveTetrimino(){ + const Uint8* ks = SDL_GetKeyboardState(NULL); + + if(!didpress){ + if(ks[SDL_SCANCODE_LEFT]){ + // TODO: IMPLEMENT + px_TetriminoMove(&tetrimino, &scene, -1, 0); + } + else if(ks[SDL_SCANCODE_RIGHT]){ + // TODO: IMPLEMENT + px_TetriminoMove(&tetrimino, &scene, +1, 0); + } + else if(ks[SDL_SCANCODE_DOWN]){ + px_TetriminoMove(&tetrimino, &scene, 0, +2); + } + else if(ks[SDL_SCANCODE_SPACE]){ + px_TetriminoDrop(&tetrimino, &scene); + } + else if(ks[SDL_SCANCODE_Z]){ + px_TetriminoRotate(&tetrimino, &scene, -1); + } + else if(ks[SDL_SCANCODE_X]){ + px_TetriminoRotate(&tetrimino, &scene, 1); + } + else{ + // No keys, Do nothing! + return; + } + + // We did press a key + didpress = true; + } + else if((!ks[SDL_SCANCODE_LEFT]) + && (!ks[SDL_SCANCODE_RIGHT]) + && (!ks[SDL_SCANCODE_DOWN]) + && (!ks[SDL_SCANCODE_SPACE]) + && (!ks[SDL_SCANCODE_Z]) + && (!ks[SDL_SCANCODE_X])){ + didpress = false; + } +} +void game_UpdateScore(SDL_Renderer* renderer){ + // A color? + SDL_Color fg = { + 255,255,255, 255 + }; + + // New Score + char* nst[10]; + sprintf(nst, "%d", scene.score); + + // Making surface + if(! (score_num_txt.surface = TTF_RenderText_Solid(score_num_txt.font, nst, fg))){ + printf("Failed to update Score(number) Surface\n"); + return; + } + + // Updating the texture + if(! (score_num_txt.texture = SDL_CreateTextureFromSurface(renderer, score_num_txt.surface))){ + printf("Failed to update Score(number) Texture\n"); + return; + } + + score_num_txt.width = score_num_txt.surface->w; + + // Cleanup + SDL_FreeSurface(score_num_txt.surface); +} + +// --HEADER +void blk_GameStart(SDL_Renderer* renderer, PX_SaveGame* savegame){ + // Making a scene + scene = px_SceneCreate(renderer, 300, 512); + tetrimino = px_TetriminoCreate(); + + // Making other elements + score_txt = px_TextCreate(renderer, "SCORE: "); + score_num_txt = px_TextCreate(renderer, "0"); + + highscore_txt = px_TextCreate(renderer, "HIGH SCORE: "); + + // Our high score! + char high_score[16]; + sprintf(high_score, "%d", savegame->high_score); + highscore_num_txt = px_TextCreate(renderer, high_score); + + // Making entities + monster = px_MonsterCreate(renderer); +} +void blk_GameUpdate(PX_SaveGame* savegame){ + // Game over.. + if(gameOver){ + // Doing an effect + // Saving the score + if(scene.score > savegame->high_score && !didWrite){ + printf("Rewrighting high score from %i to %i!\n", savegame->high_score, scene.score); + + char scoreval[16]; + sprintf(scoreval, "%d", scene.score); + + printf("Score value: %s\n", scoreval); + + px_saveWrite("save.conf", "high_score", scoreval); + + didWrite = true; + } + + return; + } + + px_TetriminoUpdate(&tetrimino, &scene); + if(tetrimino.still){ + /* + -- THIS CODE WOULD DO THIS -- + It would "delete" the current block, + and place it to the top of the screen. + */ + + // This part of the code will spawn in a NEW block and keep the old one! + px_TetriminoDraw(&tetrimino, &scene); + px_TetriminoReset(&tetrimino); + } + + // Moving the tetrimino + game_MoveTetrimino(); + + // Are we gamed over + if(tet_gameOver){ + gameOver = true; + + px_SoundPlay("res/sounds/die.wav", 0); + } + + // Updating Entities + px_MonsterUpdate(&monster, &scene); +} +void blk_GameDraw(SDL_Renderer* renderer){ + // World drawing and Scene drawing + px_TetriminoDraw(&tetrimino, &scene); + px_SceneDraw(&scene, renderer); + + // Text Updates + game_UpdateScore(renderer); + + px_TextDraw(renderer, score_txt, 300, 150, 112, 40); + px_TextDraw(renderer, score_num_txt, 400, 150, (int)(score_num_txt.width * 1.5f), 40); + px_TextDraw(renderer, highscore_txt, 300, 200, 112, 40); + px_TextDraw(renderer, highscore_num_txt, 400, 200, (int)(highscore_num_txt.width * 1.5f), 40); + + // Drawing entities + px_MosnterDraw(renderer, &scene, &monster); +} \ No newline at end of file diff --git a/src/scn/gameplay.h b/src/scn/gameplay.h new file mode 100644 index 0000000..7ca9185 --- /dev/null +++ b/src/scn/gameplay.h @@ -0,0 +1,32 @@ +// Define once +#ifndef H_GAMEPLAY +#define H_GAMEPLAY + +// Files +// --SYSTEM +#include +// --SDL +#include +// --HEADERS +#include "../gme/scene.h" +#include "../gme/tetrimino.h" +#include "../app/text.h" +#include "../app/saves.h" +#include "../gme/monster.h" + +// Scene Variables +PX_Tetrimino tetrimino; +PX_Scene scene; +bool didpress; + +// Texts +PX_Text score_txt, highscore_txt; +PX_Text score_num_txt, highscore_num_txt; + +// Functions +void blk_GameStart(SDL_Renderer* renderer, PX_SaveGame* savegame); +void blk_GameUpdate(PX_SaveGame* savegame); +void blk_GameDraw(SDL_Renderer* renderer); + +// End definition +#endif \ No newline at end of file diff --git a/src/scn/mainmenu.c b/src/scn/mainmenu.c new file mode 100644 index 0000000..092234f --- /dev/null +++ b/src/scn/mainmenu.c @@ -0,0 +1,73 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +// --HEADERS +#include "../app/features.h" +#include "../app/texture.h" +#include "../app/dtime.h" +#include "../app/text.h" +#include "mainmenu.h" + +// Variables +float _time; +float stpos; + +// Functions +// --HELPER +void blk_MMSTART(){ + stpos = Lerp(stpos, 350, 0.05f); + + if(stpos <= 353){ + stpos = 350; + px_mcanstart = true; + } +} + +// --BASE +void blk_MMCreate(SDL_Renderer* renderer){ + // Init SDL2_IMG + IMG_Init(IMG_INIT_PNG); + + // Creating textures and what not + titletex = (SDL_Texture*)malloc(16 * sizeof(int)); + titletex = px_TextureCreate(renderer, "res/sprites/title.png"); + + // Making the title thing + start_txt = px_TextCreate(renderer, "Press [SPACE] to start."); + + // Making the time + _time = 0; + stpos = 600; + px_mcanstart = false; +} +void blk_MMUpdate(){ + // Adding time + _time += (float)deltatime * 1.2f; + + // Allowing the menu to transition + blk_MMSTART(); +} +void blk_MMDraw(SDL_Renderer* renderer){ + // Color + SDL_SetRenderDrawColor(renderer, 0,0,0, 1); + + // Making the title card + SDL_Rect titlecard; + + titlecard.x = 100 + (int)(cosf(_time / 200) * 10); + titlecard.y = 10 + (int)(sinf(_time / 100) * 10); + titlecard.w = 300; titlecard.h = 300; + + SDL_RenderFillRect(renderer, &titlecard); + SDL_RenderCopy(renderer, titletex, NULL, &titlecard); + + // Making the start text + px_TextDraw(renderer, start_txt, 100, stpos, 300, 50); +} +void blk_MMClean(){ + SDL_FreeSurface(start_txt.surface); + free(titletex); +} \ No newline at end of file diff --git a/src/scn/mainmenu.h b/src/scn/mainmenu.h new file mode 100644 index 0000000..1e99dc2 --- /dev/null +++ b/src/scn/mainmenu.h @@ -0,0 +1,27 @@ +// Define once +#ifndef H_MAINMENU +#define H_MAINMENU + +// Files +// --SYSTEM +#include +// --SDL +#include +#include +// --HEADERS +#include "../app/text.h" + +// CONSTANTS +// VARIABLES +SDL_Texture* titletex; +PX_Text start_txt; +bool px_mcanstart; + +// Functions +void blk_MMCreate(SDL_Renderer* renderer); +void blk_MMUpdate(); +void blk_MMDraw(SDL_Renderer* renderer); +void blk_MMClean(); + +// End definition +#endif \ No newline at end of file diff --git a/src/scn/splash.c b/src/scn/splash.c new file mode 100644 index 0000000..182b7ef --- /dev/null +++ b/src/scn/splash.c @@ -0,0 +1,91 @@ +// Files +// --SYSTEM +#include +#include +// --SDL +#include +// --HEADERS +#include "splash.h" +#include "../app/features.h" +#include "../app/texture.h" +#include "../app/dtime.h" +#include "../app/sound.h" + +// Variables +SDL_Texture* splashtex; + +int wid, hig; +int spx,spy; +int spf; + +float stillt; + +bool fading, playedding; + +// Functions +void px_SSstart(SDL_Renderer* renderer, int width, int height){ + // Making a texture + splashtex = (SDL_Texture*)malloc(32 * sizeof(int)); + splashtex = px_TextureCreate(renderer, "res/sprites/primax.png"); + SDL_SetTextureBlendMode(splashtex, SDL_BLENDMODE_BLEND); + + // Setting variables + px_ssready = false; + playedding = false; + fading = false; + + wid = width; hig = height; + + spx = (int)(width / 2); + spy = (int)(height * 1.5f); + + spf = 255; +} +void px_SSupdate(){ + // Moving the logo to center + spy = Lerp(spy, hig / 2, 0.05f); + + // Are we ready? + if(abs(spy - (hig / 2)) <= 5){ + if(stillt >= 5.0f){ + fading = true; + } + else{ + stillt += deltatime * (120.0f/1000.0f); + } + + if(!playedding){ + px_SoundPlay("res/sounds/primaxding.wav", 0); + playedding = true; + } + } + if(fading){ // Fading + spf = Lerp(spf, 0, 0.02f * deltatime); + if(spf <= 3) {px_ssready = true;} + } +} +void px_SSdraw(SDL_Renderer* renderer, int width, int height){ + // The clear color + SDL_SetRenderDrawColor(renderer, 0,0,0, 1); + + // Making the rect + SDL_Rect rect; + + // Constants + const int rsize = 400; + + // Setting the positional stuff + rect.w = rsize; rect.h = rsize; + rect.x = spx - (int)(rsize / 2.0f); + rect.y = spy - (int)(rsize / 2.0f); + + SDL_SetTextureAlphaMod(splashtex, spf); + + // Drawing the rectangle + SDL_RenderFillRect(renderer, &rect); + SDL_RenderCopy(renderer, splashtex, NULL, &rect); +} +void px_SSclean(){ + // Free All variables + free(splashtex); +} \ No newline at end of file diff --git a/src/scn/splash.h b/src/scn/splash.h new file mode 100644 index 0000000..2fea792 --- /dev/null +++ b/src/scn/splash.h @@ -0,0 +1,24 @@ +// Define once +#ifndef H_SPLASH +#define H_SPLASH + +// Files +// --SYSTEM +#include +#include +// --SDL +#include +// --HEADERS +#include "../app/dtime.h" + +// Variables +bool px_ssready; + +// Functions +void px_SSstart(SDL_Renderer* renderer, int width, int height); +void px_SSupdate(); +void px_SSdraw(SDL_Renderer* renderer, int width, int height); +void px_SSclean(); + +// End definition +#endif \ No newline at end of file