Added sdl version to exmplify extension of the main engine
This commit is contained in:
parent
8cff1bb002
commit
3dd23136d5
7
Makefile
7
Makefile
|
@ -1,7 +1,7 @@
|
||||||
CC := clang
|
CC := clang
|
||||||
CFLAGS += -O2 -Wall -Wextra
|
CFLAGS += -g -Wall -Wextra
|
||||||
LFLAGS +=
|
LFLAGS +=
|
||||||
DEFINES := -DVT100
|
DEFINES := -DVT100 -D_REENTRANT -I/usr/include/SDL2
|
||||||
|
|
||||||
PROGRAM := 2048
|
PROGRAM := 2048
|
||||||
C_FILES := $(wildcard src/*.c)
|
C_FILES := $(wildcard src/*.c)
|
||||||
|
@ -15,6 +15,9 @@ curses: $(O_FILES)
|
||||||
vt100: $(O_FILES)
|
vt100: $(O_FILES)
|
||||||
$(CC) $(filter-out obj/gfx%.o, $(O_FILES)) obj/gfx_terminal.o -o $(PROGRAM)
|
$(CC) $(filter-out obj/gfx%.o, $(O_FILES)) obj/gfx_terminal.o -o $(PROGRAM)
|
||||||
|
|
||||||
|
sdl: $(O_FILES)
|
||||||
|
$(CC) $(filter-out obj/gfx%.o, $(O_FILES)) obj/gfx_sdl.o -o $(PROGRAM) -lSDL2 -lSDL2_ttf
|
||||||
|
|
||||||
obj/%.o: src/%.c
|
obj/%.o: src/%.c
|
||||||
$(CC) $(DEFINES) $(CFLAGS) -c -o $@ $<
|
$(CC) $(DEFINES) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
|
25
README.md
25
README.md
|
@ -1,24 +1,25 @@
|
||||||
#2048-cli
|
#2048-cli
|
||||||
|
|
||||||
A cli version of the game [2048](https://github.com/gabrielecirulli/2048) for your Linux
|
A cli version/engine of the game [2048](https://github.com/gabrielecirulli/2048) for your Linux
|
||||||
terminal.
|
terminal.
|
||||||
|
|
||||||
#####2048_curses.c
|
|
||||||
![Screenshot](http://i.imgur.com/QU7t5mH.png)
|
![Screenshot](http://i.imgur.com/QU7t5mH.png)
|
||||||
|
|
||||||
#####2048_no_curses.c
|
There currently are 3 versions that can be run. These include a straight-forward terminal
|
||||||
![Screenshot](http://i.imgur.com/fwZEvdh.png)
|
based, and two using the ncurses and SDL libraries. To add a new graphical version, simply
|
||||||
|
create a .c file which implements all the functions in gfx.h and add a Makefile entry.
|
||||||
## Installation
|
|
||||||
This requires the ncurses library to link against during compilation. It is available
|
|
||||||
in most package managers. The program creates and uses a file name `.hs2048g` in the
|
|
||||||
working directory. Any file with this name will be modified and replaced.
|
|
||||||
|
|
||||||
### Get
|
### Get
|
||||||
git clone https://github.com/Tiehuis/2048-cli.git
|
git clone https://github.com/Tiehuis/2048-cli.git
|
||||||
make
|
|
||||||
|
make vt100
|
||||||
|
or
|
||||||
|
make curses
|
||||||
|
or
|
||||||
|
make sdl
|
||||||
|
|
||||||
### Run
|
### Run
|
||||||
./2048
|
./2048
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
-s <size> Set the grid border length
|
-s <size> Set the grid border length
|
||||||
|
@ -27,5 +28,7 @@ working directory. Any file with this name will be modified and replaced.
|
||||||
-c Enables color support (ncurses version only)
|
-c Enables color support (ncurses version only)
|
||||||
-C Disables color support (ncurses version only)
|
-C Disables color support (ncurses version only)
|
||||||
|
|
||||||
|
Fonts used in SDL version can be found [here](openfontlibrary.org).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This code is licensed under the [MIT License](https://github.com/Tiehuis/2048-cli/blob/master/LICENSE).
|
This code is licensed under the [MIT License](https://github.com/Tiehuis/2048-cli/blob/master/LICENSE).
|
||||||
|
|
BIN
res/Anonymous Pro.ttf
Normal file
BIN
res/Anonymous Pro.ttf
Normal file
Binary file not shown.
BIN
res/NotCourierSans.ttf
Normal file
BIN
res/NotCourierSans.ttf
Normal file
Binary file not shown.
|
@ -270,7 +270,6 @@ int gamestate_tick(struct gfx_state *s, struct gamestate *g, int d, void (*callb
|
||||||
{
|
{
|
||||||
/* Reset move. Altered by gravitate and merge if we do move */
|
/* Reset move. Altered by gravitate and merge if we do move */
|
||||||
g->moved = 0;
|
g->moved = 0;
|
||||||
printf("%d\n", d);
|
|
||||||
gravitate(s, g, d, callback);
|
gravitate(s, g, d, callback);
|
||||||
merge(s, g, d, callback);
|
merge(s, g, d, callback);
|
||||||
gravitate(s, g, d, callback);
|
gravitate(s, g, d, callback);
|
||||||
|
|
181
src/gfx_sdl.c
Normal file
181
src/gfx_sdl.c
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_ttf.h>
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
/* Side length of a 'pixel' in pixels */
|
||||||
|
#define TTF_FONT_PATH "res/Anonymous Pro.ttf"
|
||||||
|
#define TTF_FONT_PT 32
|
||||||
|
|
||||||
|
#define iterate(n, expression)\
|
||||||
|
do {\
|
||||||
|
int i;\
|
||||||
|
for (i = 0; i < n; ++i) { expression; }\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct gfx_state {
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_Surface *surface;
|
||||||
|
TTF_Font *font;
|
||||||
|
int side_length;
|
||||||
|
int window_height;
|
||||||
|
int window_width;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gfx_state* gfx_init(struct gamestate *g)
|
||||||
|
{
|
||||||
|
struct gfx_state *s = malloc(sizeof(struct gfx_state));
|
||||||
|
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
TTF_Init();
|
||||||
|
s->font = TTF_OpenFont(TTF_FONT_PATH, TTF_FONT_PT);
|
||||||
|
|
||||||
|
s->side_length = TTF_FontLineSkip(s->font);
|
||||||
|
s->window_height = g->opts->grid_height * (g->print_width + 2) + 3;
|
||||||
|
s->window_width = g->opts->grid_width * (g->print_width + 2) + 1;
|
||||||
|
s->window = SDL_CreateWindow(
|
||||||
|
"2048",
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
|
||||||
|
/* Spacing is inconsistent right now. Need to find width and
|
||||||
|
* height spacing to accurately resize window */
|
||||||
|
s->window_width * TTF_FONT_PT * 0.7,
|
||||||
|
s->window_height * s->side_length * 0.35,
|
||||||
|
SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
|
||||||
|
);
|
||||||
|
|
||||||
|
s->surface = SDL_GetWindowSurface(s->window);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define rect_set(r, xv, yv, wv, hv)\
|
||||||
|
do {\
|
||||||
|
r.x = xv; r.y = yv; r.w = wv; r.h = hv;\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
void gfx_draw(struct gfx_state *s, struct gamestate *g)
|
||||||
|
{
|
||||||
|
/* This shouldn't ever overflow. Max width effectively is determined by the size
|
||||||
|
* of two integers' text representation */
|
||||||
|
const int buffer_length = 64;
|
||||||
|
char string_buffer[buffer_length];
|
||||||
|
|
||||||
|
/* Set up text object so we can write to sdl window */
|
||||||
|
SDL_Surface *text;
|
||||||
|
SDL_Color text_color = {255, 255, 255, 0};
|
||||||
|
SDL_Rect rect;
|
||||||
|
|
||||||
|
/* Clear screen */
|
||||||
|
SDL_FillRect(s->surface, NULL, SDL_MapRGB(s->surface->format, 0, 0, 0));
|
||||||
|
|
||||||
|
if (g->score_last)
|
||||||
|
snprintf(string_buffer, buffer_length, "Score: %ld (+%ld)", g->score, g->score_last);
|
||||||
|
else
|
||||||
|
snprintf(string_buffer, buffer_length, "Score: %ld", g->score);
|
||||||
|
|
||||||
|
rect_set(rect, 0, 0, 0, 0);
|
||||||
|
text = TTF_RenderText_Solid(s->font, string_buffer, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, s->surface, &rect);
|
||||||
|
|
||||||
|
snprintf(string_buffer, buffer_length, " Hi: %ld", g->score_high);
|
||||||
|
rect_set(rect, 0, s->side_length * 1, 0, 0);
|
||||||
|
text = TTF_RenderText_Solid(s->font, string_buffer, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, s->surface, &rect);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < g->opts->grid_width * (g->print_width + 2) + 1; ++i)
|
||||||
|
string_buffer[i] = '-';
|
||||||
|
string_buffer[i] = '\0';
|
||||||
|
|
||||||
|
rect_set(rect, 0, s->side_length * 2, 0, 0);
|
||||||
|
text = TTF_RenderText_Solid(s->font, string_buffer, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, s->surface, &rect);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
char line_buffer[buffer_length];
|
||||||
|
for (y = 0; y < g->opts->grid_height; ++y) {
|
||||||
|
int line_index = 0;
|
||||||
|
line_buffer[line_index++] = '|';
|
||||||
|
|
||||||
|
for (x = 0; x < g->opts->grid_width; ++x) {
|
||||||
|
if (g->grid[x][y]) {
|
||||||
|
snprintf(string_buffer, buffer_length, "%*ld |", g->print_width, g->grid[x][y]);
|
||||||
|
strncpy(line_buffer + line_index, string_buffer, buffer_length - line_index);
|
||||||
|
line_index += strlen(string_buffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(string_buffer, buffer_length, "%*s |", g->print_width, "");
|
||||||
|
strncpy(line_buffer + line_index, string_buffer, buffer_length - line_index);
|
||||||
|
line_index += strlen(string_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line_buffer[line_index] = 0;
|
||||||
|
rect_set(rect, 0, s->side_length * (y + 3), 0, 0);
|
||||||
|
text = TTF_RenderText_Solid(s->font, line_buffer, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, s->surface, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g->opts->grid_height * (g->print_width + 2) + 1; ++i)
|
||||||
|
string_buffer[i] = '-';
|
||||||
|
string_buffer[i] = '\0';
|
||||||
|
|
||||||
|
rect_set(rect, 0, s->side_length * (y + 3), 0, 0);
|
||||||
|
text = TTF_RenderText_Solid(s->font, string_buffer, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, s->surface, &rect);
|
||||||
|
SDL_UpdateWindowSurface(s->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This getch we parse here, and we just return when we get an appropriate
|
||||||
|
* event */
|
||||||
|
int gfx_getch(struct gfx_state *s)
|
||||||
|
{
|
||||||
|
(void)s; /* Supress unused warning */
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
while (SDL_WaitEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
|
return 'q';
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_q:
|
||||||
|
return 'q';
|
||||||
|
case SDLK_UP:
|
||||||
|
case SDLK_w:
|
||||||
|
return 'w';
|
||||||
|
case SDLK_DOWN:
|
||||||
|
case SDLK_s:
|
||||||
|
return 's';
|
||||||
|
case SDLK_LEFT:
|
||||||
|
case SDLK_a:
|
||||||
|
return 'a';
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
case SDLK_d:
|
||||||
|
return 'd';
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_sleep(int ms)
|
||||||
|
{
|
||||||
|
SDL_Delay(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_destroy(struct gfx_state *s)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(s->window);
|
||||||
|
TTF_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user