├── .gitignore ├── Makefile ├── README.md ├── assets ├── fonts │ └── FONT.TTF ├── map.tmx ├── music │ └── song.mp3 ├── sprites │ ├── character.png │ ├── held_weapons.png │ └── soldier.png └── tiles.png ├── prettify └── src ├── animation.c ├── animation.h ├── collision.c ├── collision.h ├── entity.c ├── entity.h ├── game.c ├── game.h ├── main.c ├── music.c ├── music.h ├── render.c ├── render.h ├── util.c └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | game 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=cc 2 | SRCDIR=src 3 | ASSETS="assets/" 4 | FLAGS=-Wall -Werror -std=c99 -DASSETS='$(ASSETS)' -c -g 5 | LIBS=-lSDL2 -lSDL2_ttf -lSDL2_mixer -lSDL2_image -ltmx -ljansson -lxml2 -lz -lm 6 | SRC=$(wildcard $(SRCDIR)/*.c) 7 | OBJS=$(notdir $(SRC:.c=.o)) 8 | OUT=game 9 | 10 | all: $(OUT) 11 | 12 | $(OUT): $(OBJS) 13 | $(CC) $(OBJS) -o $(OUT) $(LIBS) 14 | 15 | %.o: $(SRCDIR)/%.c 16 | $(CC) $(FLAGS) $< 17 | 18 | clean: 19 | rm -f $(OUT) $(OBJS) 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | game 2 | ==== 3 | 4 | A game made by members of [nixers](http://nixers.net). The current plan is a 5 | "top-down RPG with a cyberpunk setting". We are writing it in C and SDL. We 6 | have a forum thread [here](http://nixers.net/showthread.php?tid=1621), and 7 | regularly discuss development over at [#game](irc://irc.nixers.net/#game) on 8 | irc.nixers.net. 9 | 10 | Dependencies 11 | ------------ 12 | 13 | * [tmx](https://github.com/baylej/tmx), which depends on 14 | * zlib 15 | * jansson 16 | * libxml2 17 | * sdl2 (might as well get the whole suite) 18 | 19 | Building 20 | -------- 21 | 22 | To build the project, simply use 23 | 24 | ```Bash 25 | make 26 | ``` 27 | 28 | And run the binary 29 | 30 | ```Bash 31 | ./game 32 | ``` 33 | 34 | The name of the binary is subject to change, and we'll add install/deinstall 35 | targets in the future, so keep an eye out. 36 | 37 | Contributing 38 | ------------ 39 | 40 | Generally we advise people make forks and pull requests. It allows us to 41 | discuss changes before it's too late and means we won't have issues with conflicting commits. Be sure to 42 | hop on IRC for the most up-to-date discussions. 43 | 44 | Style 45 | ----- 46 | 47 | The `prettify` script uses [astyle](http://astyle.sourceforge.net) to 48 | automatically format the code, please use it. We will reject or at least ask 49 | you to run astyle on any pull requests that are not formatted correctly. 50 | -------------------------------------------------------------------------------- /assets/fonts/FONT.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/fonts/FONT.TTF -------------------------------------------------------------------------------- /assets/map.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | eJztwwEJAAAMBKH7/qUHy6Hgqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv8AX0MnEQ== 9 | 10 | 11 | 12 | 13 | eJzt1sEJgDAUBcF4sP+WbUCIICQLmYV31s948B5j3GZmZj+3ut3P390qj+vD3t7ntHi04tGKRyserfxfteLRikcrHq14tOLRikcrHq14tKp5nB6PVjxa8WjFoxWPVjxa8WjFoxWPVjxa8WjFoxWPVjxa8WjFoxWPVjxa8WhV8pi9ywnfSulmHq2bebRu5nHmzeV4tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq14tOLRikcrHq1mHmZmZl/2AKPVIEo= 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /assets/music/song.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/music/song.mp3 -------------------------------------------------------------------------------- /assets/sprites/character.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/sprites/character.png -------------------------------------------------------------------------------- /assets/sprites/held_weapons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/sprites/held_weapons.png -------------------------------------------------------------------------------- /assets/sprites/soldier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/sprites/soldier.png -------------------------------------------------------------------------------- /assets/tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nixers-projects/game/ffd2eeb5ecd89bd653f0065bce107dc1ab30efb1/assets/tiles.png -------------------------------------------------------------------------------- /prettify: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | astyle --style=knf -s4 -n src/* 3 | -------------------------------------------------------------------------------- /src/animation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "animation.h" 3 | #include "util.h" 4 | 5 | #ifndef ASSETS 6 | #define ASSETS "assets/" 7 | #endif 8 | 9 | 10 | static SDL_Surface* loadImage(char *path) 11 | { 12 | SDL_Surface *img = IMG_Load(path); 13 | if(!img) { 14 | fprintf(stderr,"IMG_Load: %s\n", IMG_GetError()); 15 | return NULL; 16 | } 17 | return img; 18 | } 19 | 20 | 21 | void animationLoadAssets(SDL_Renderer *ren) 22 | { 23 | char *path = buildPath(ASSETS, "sprites/held_weapons.png"); 24 | SDL_Surface *img = loadImage(path); 25 | 26 | TextureWeapons = SDL_CreateTextureFromSurface(ren, img); 27 | 28 | path = buildPath(ASSETS, "sprites/soldier.png"); 29 | img = loadImage(path); 30 | TextureSoldier = SDL_CreateTextureFromSurface(ren, img); 31 | 32 | WeaponSMG = (heldWeapon) { 33 | (SDL_Rect) { 64, 0, 64, 64 }, 34 | 5, -15 35 | }; 36 | 37 | free(path); 38 | SDL_FreeSurface(img); 39 | } 40 | 41 | animation* CreateAnimation(SDL_Renderer *ren, SDL_Texture *tex, SDL_Rect *frames, 42 | int numFrames, float timeBetweenFrames) 43 | { 44 | animation *anim = malloc(sizeof(animation)); 45 | anim->tex = tex; 46 | anim->numFrames = numFrames; 47 | anim->currentFrame = 0; 48 | anim->elapsedTime = 0; 49 | anim->timeBetweenFrames = timeBetweenFrames; 50 | anim->frames = frames; 51 | 52 | return anim; 53 | } 54 | 55 | void updateAnimation(animation* anim, float deltaTimeS) 56 | { 57 | anim->elapsedTime += deltaTimeS; 58 | if(anim->elapsedTime >= anim->timeBetweenFrames) { 59 | anim->elapsedTime = 0; 60 | if (anim->currentFrame >= anim->numFrames) anim->currentFrame = 0; 61 | else anim->currentFrame += 1; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/animation.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ANIMATION_MAX_FRAMES 10 4 | 5 | // TODO: Load all textures globally! 6 | SDL_Texture *TextureWeapons; 7 | SDL_Texture *TextureSoldier; 8 | 9 | typedef struct animation { 10 | int numFrames; 11 | int currentFrame; 12 | SDL_Rect *frames; 13 | float elapsedTime,timeBetweenFrames; 14 | SDL_Texture *tex; 15 | } animation; 16 | 17 | typedef struct heldWeapon { 18 | SDL_Rect src; 19 | int x_offset, y_offset; 20 | } heldWeapon; 21 | 22 | heldWeapon WeaponSMG; 23 | 24 | void animationLoadAssets(SDL_Renderer *ren); 25 | 26 | // numFrames with zero index 27 | animation* CreateAnimation(SDL_Renderer *ren, SDL_Texture *tex, SDL_Rect *frames, 28 | int numFrames, float timeBetweenFrames); 29 | void updateAnimation(animation* e, float deltaTimeS); 30 | -------------------------------------------------------------------------------- /src/collision.c: -------------------------------------------------------------------------------- 1 | #include "SDL2/SDL.h" 2 | #include "collision.h" 3 | #include "game.h" 4 | 5 | bool checkCollision(SDL_Rect *rect,entity* self) 6 | { 7 | for (int i = 0; i < MAX_ENTITIES; i++) { 8 | if(entities[i] != NULL && entities[i] != self) { 9 | SDL_Rect r; 10 | r.x = entities[i]->x; 11 | r.y = entities[i]->y; 12 | r.w = entities[i]->w; 13 | r.h = entities[i]->h; 14 | if(SDL_HasIntersection(rect,&r)) { 15 | return true; 16 | } 17 | } 18 | } 19 | // Check for map collision 20 | for (int i = 0; i < (int)collision_map.size; i++) { 21 | if(SDL_HasIntersection(rect, &collision_map.array[i])) { 22 | return true; 23 | } 24 | } 25 | return false; 26 | } 27 | 28 | void initMapObjectArr(map_object_arr *a, size_t initialSize) 29 | { 30 | a->array = (SDL_Rect *)malloc(initialSize * sizeof(SDL_Rect)); 31 | a->used = 0; 32 | a->size = initialSize; 33 | } 34 | 35 | void insertMapObjectArr(map_object_arr *a, SDL_Rect element) 36 | { 37 | if (a->used == a->size) { 38 | a->size *= 2; 39 | a->array = (SDL_Rect *)realloc(a->array, a->size * sizeof(SDL_Rect)); 40 | } 41 | a->array[a->used++] = element; 42 | } 43 | 44 | void freeMapObjectArr(map_object_arr *a) 45 | { 46 | free(a->array); 47 | a->array = NULL; 48 | a->used = a->size = 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/collision.h: -------------------------------------------------------------------------------- 1 | #ifndef COLLISION_H 2 | #define COLLISION_H 3 | 4 | #include 5 | #include "SDL2/SDL.h" 6 | #include "entity.h" 7 | 8 | typedef struct { 9 | SDL_Rect *array; 10 | size_t used; 11 | size_t size; 12 | } map_object_arr; 13 | 14 | // Saves collision points for map 15 | map_object_arr collision_map; 16 | 17 | bool checkCollision(SDL_Rect*,entity*); 18 | 19 | // collsision_map stuff 20 | void initMapObjectArr(map_object_arr *a, size_t initialSize); 21 | void insertMapObjectArr(map_object_arr *a, SDL_Rect element); 22 | void freeMapObjectArr(map_object_arr *a); 23 | 24 | #endif // COLLISION_H 25 | -------------------------------------------------------------------------------- /src/entity.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "entity.h" 4 | #include "game.h" 5 | #include "render.h" 6 | #include "collision.h" 7 | 8 | entity* CreateEntity(int x, int y, int w, int h, animation legs, 9 | SDL_Rect torso) 10 | { 11 | entity *e = malloc(sizeof(entity)); 12 | e->x = x; 13 | e->y = y; 14 | e->w = w; 15 | e->h = h; 16 | e->x_vel = 0; 17 | e->y_vel = 0; 18 | e->velocity = 70; 19 | e->legs = legs; 20 | e->torso = torso; 21 | e->torso_tex = TextureSoldier; 22 | e->type = ENTITY_TYPE_DEFAULT; 23 | e->torso_angle = 0.0f; 24 | e->torso_center = (SDL_Point) { 25 | 32, 32 26 | }; 27 | e->weapon = NULL; 28 | return e; 29 | } 30 | 31 | void updateEntityTorsoToWeapon(SDL_Renderer *ren, entity *e, heldWeapon *weapon) 32 | { 33 | e->torso_tex = renderWeaponToTexture(ren, weapon, 34 | e->torso_tex, &e->torso); 35 | e->torso.x = 0; 36 | e->torso.y = 0; 37 | } 38 | 39 | void updateEntity(entity *e, float deltaTimeS) 40 | { 41 | updateAnimation(&e->legs, deltaTimeS); 42 | switch (e->type) { 43 | case ENTITY_TYPE_DEFAULT: 44 | if (character->x < e->x) entity_move_left(e, deltaTimeS); 45 | if (character->x > e->x) entity_move_right(e, deltaTimeS); 46 | if (character->y < e->y) entity_move_up(e, deltaTimeS); 47 | if (character->y > e->y) entity_move_down(e, deltaTimeS); 48 | entity_move(e, e->x + e->x_vel, e->y + e->y_vel); 49 | break; 50 | case ENTITY_TYPE_MAIN_CHARACTER: 51 | entity_move(e, e->x + e->x_vel, e->y + e->y_vel); 52 | break; 53 | case ENTITY_TYPE_PET: 54 | if (character->x - 25 < e->x) entity_move_left(e, deltaTimeS); 55 | if (character->x + 25 > e->x) entity_move_right(e, deltaTimeS); 56 | if (character->y - 25 < e->y) entity_move_up(e, deltaTimeS); 57 | if (character->y + 25 > e->y) entity_move_down(e, deltaTimeS); 58 | entity_move(e, e->x + e->x_vel, e->y + e->y_vel); 59 | break; 60 | default: 61 | printf("Invalid entity type"); 62 | break; 63 | } 64 | } 65 | 66 | // Moves entity to new position if possible 67 | void entity_move(entity *e, float x, float y) 68 | { 69 | if(x != e->x) { 70 | SDL_Rect newRect; 71 | newRect.x = x; 72 | newRect.y = e->y; 73 | newRect.w = e->w; 74 | newRect.h = e->h; 75 | if(!checkCollision(&newRect,e)) e->x = x; 76 | } 77 | if(y != e->y) { 78 | SDL_Rect newRect; 79 | newRect.x = e->x; 80 | newRect.y = y; 81 | newRect.w = e->w; 82 | newRect.h = e->h; 83 | if(!checkCollision(&newRect,e)) e->y = y; 84 | } 85 | } 86 | 87 | void eventEntity(entity * e, SDL_Event event, float deltaTimeS) 88 | { 89 | if (event.type == SDL_KEYDOWN) { 90 | SDL_Scancode key = event.key.keysym.scancode; 91 | if (key == SDL_SCANCODE_A) { 92 | entity_move_left(e, deltaTimeS); 93 | } else if (key == SDL_SCANCODE_D) { 94 | entity_move_right(e, deltaTimeS); 95 | } else if (key == SDL_SCANCODE_S) { 96 | entity_move_down(e, deltaTimeS); 97 | } else if (key == SDL_SCANCODE_W) { 98 | entity_move_up(e, deltaTimeS); 99 | } 100 | } else if(event.type == SDL_KEYUP) { 101 | SDL_Scancode key = event.key.keysym.scancode; 102 | if (key == SDL_SCANCODE_A || key == SDL_SCANCODE_D) { 103 | character->x_vel = 0; 104 | } else if (key == SDL_SCANCODE_S || key == SDL_SCANCODE_W) { 105 | character->y_vel = 0; 106 | } 107 | } else if (event.type == SDL_MOUSEMOTION) { 108 | // Check main.c! 109 | 110 | /*int deltaX = event.motion.x + camera.x - (e->x + 32);*/ 111 | /*int deltaY = event.motion.y + camera.y - (e->y + 32);*/ 112 | /*e->torso_angle = atan2(deltaY, deltaX) * 180 / PI;*/ 113 | } 114 | } 115 | 116 | void entity_move_left(entity *e, float deltaTimeS) 117 | { 118 | e->x_vel = e->velocity * -deltaTimeS; 119 | e->legs_angle = 270; 120 | } 121 | 122 | void entity_move_right(entity *e, float deltaTimeS) 123 | { 124 | e->x_vel = e->velocity * deltaTimeS; 125 | e->legs_angle = 90; 126 | } 127 | void entity_move_up(entity *e, float deltaTimeS) 128 | { 129 | e->y_vel = e->velocity * -deltaTimeS; 130 | e->legs_angle = 0; 131 | } 132 | 133 | void entity_move_down(entity *e, float deltaTimeS) 134 | { 135 | e->y_vel = e->velocity * deltaTimeS; 136 | e->legs_angle = 180; 137 | } 138 | -------------------------------------------------------------------------------- /src/entity.h: -------------------------------------------------------------------------------- 1 | #ifndef ENTITY_H 2 | #define ENTITY_H 3 | 4 | #include 5 | #include "animation.h" 6 | 7 | #define ENTITY_TYPE_DEFAULT 0 8 | #define ENTITY_TYPE_MAIN_CHARACTER 1 9 | #define ENTITY_TYPE_PET 2 10 | 11 | typedef struct { 12 | // pos 13 | float x, y; 14 | // body size 15 | float w,h; 16 | float x_vel, y_vel; 17 | float velocity; 18 | int type; 19 | double torso_angle; 20 | double legs_angle; 21 | SDL_Point torso_center; 22 | 23 | // animation 24 | animation legs; 25 | SDL_Rect torso; 26 | SDL_Texture *torso_tex; 27 | heldWeapon *weapon; 28 | } entity; 29 | 30 | entity* CreateEntity(int x, int y, int w, int h, animation legs, SDL_Rect torso); 31 | void updateEntityTorsoToWeapon(SDL_Renderer *ren, entity *e, heldWeapon *weapon); 32 | 33 | void updateEntity(entity *e, float deltaTimeS); 34 | void eventEntity(entity * e, SDL_Event event, float deltaTimeS); 35 | 36 | // Use these functions to move the entity 37 | void entity_move_left(entity*, float); 38 | void entity_move_right(entity*, float); 39 | void entity_move_up(entity*, float); 40 | void entity_move_down(entity*, float); 41 | 42 | void entity_move(entity*, float, float); 43 | #endif // ENTITY_H 44 | -------------------------------------------------------------------------------- /src/game.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "game.h" 7 | #include "entity.h" 8 | #include "util.h" 9 | #include "collision.h" 10 | #include "render.h" 11 | 12 | #ifndef ASSETS 13 | #define ASSETS "assets/" 14 | #endif 15 | 16 | void game_init(SDL_Renderer *ren) 17 | { 18 | for (int i = 0; i < MAX_ENTITIES; i++) { 19 | entities[i] = NULL; 20 | } 21 | 22 | animationLoadAssets(ren); 23 | 24 | SDL_Rect *frames = malloc(sizeof(SDL_Rect) * 4); 25 | frames[0] = (SDL_Rect) { 26 | 0, 0, 64, 64 27 | }; 28 | frames[1] = (SDL_Rect) { 29 | 64, 0, 64, 64 30 | }; 31 | frames[2] = (SDL_Rect) { 32 | 128, 0, 64, 64 33 | }; 34 | frames[3] = (SDL_Rect) { 35 | 0, 64, 64, 64 36 | }; 37 | 38 | animation *legs = CreateAnimation(ren, TextureSoldier, frames, 3, 0.2); 39 | 40 | character = CreateEntity(100, 100, 24,32, *legs, (SDL_Rect) { 41 | 64, 64, 64, 64 42 | }); 43 | character->type = ENTITY_TYPE_MAIN_CHARACTER; 44 | character->velocity = 80; 45 | character->w = 64; 46 | character->h = 64; 47 | entities[0] = character; 48 | 49 | updateEntityTorsoToWeapon(ren, character, &WeaponSMG); 50 | 51 | entity *e = CreateEntity(300, 300, 24,32, *legs, (SDL_Rect) { 52 | 64, 64, 64, 64 53 | }); 54 | e->type = ENTITY_TYPE_DEFAULT; 55 | e->velocity = 60; 56 | e->w = 64; 57 | e->h = 64; 58 | entities[1] = e; 59 | 60 | char *path = buildPath(ASSETS, "map.tmx"); 61 | /* You probably want to create a fuction that creates a SDL_Texture directly here */ 62 | // https://github.com/baylej/tmx/blob/master/examples/sdl.c 63 | tmx_img_load_func = (void* (*)(const char*))IMG_Load; 64 | tmx_img_free_func = (void (*)(void*)) SDL_FreeSurface; 65 | 66 | if (!(map = tmx_load("assets/map.tmx"))) 67 | tmx_perror("tmpx_err"); 68 | 69 | map_rect.w = map->width * map->tile_width; 70 | map_rect.h = map->height * map->tile_height; 71 | map_rect.x = 0; 72 | map_rect.y = 0; 73 | 74 | free(path); 75 | } 76 | -------------------------------------------------------------------------------- /src/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include 5 | #include "entity.h" 6 | 7 | #define MAX_ENTITIES 100 8 | 9 | tmx_map *map; 10 | SDL_Rect map_rect; 11 | 12 | entity *entities[MAX_ENTITIES]; 13 | entity *character; 14 | 15 | void game_init(); 16 | 17 | #endif // GAME_H 18 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "SDL2/SDL.h" 5 | #include "SDL2/SDL_ttf.h" 6 | #include "SDL2/SDL_mixer.h" 7 | #include "SDL2/SDL_image.h" 8 | 9 | #include "entity.h" 10 | #include "game.h" 11 | #include "music.h" 12 | #include "util.h" 13 | #include "render.h" 14 | 15 | #define WINDOW_TITLE "Game" 16 | #define MAX_FPS 100 17 | 18 | #define PI 4*atan(1.0) 19 | 20 | #ifndef ASSETS 21 | #define ASSETS "assets/" 22 | #endif 23 | 24 | // Main window 25 | SDL_Window *screen; 26 | SDL_Renderer *renderer; 27 | 28 | TTF_Font *font; 29 | 30 | SDL_Texture *curr_buffer; 31 | SDL_Texture *map_tex; 32 | 33 | Sint32 mouse_x; 34 | Sint32 mouse_y; 35 | 36 | double deltaX; 37 | double deltaY; 38 | int debug_line_num = 0; 39 | 40 | void draw_debug_line(char *str, int len) 41 | { 42 | SDL_Color background = { 0, 0, 0, 0 }; 43 | SDL_Color foreground = { 255, 255, 255, 0 }; 44 | 45 | SDL_Surface *textSurface = TTF_RenderText(font, str, foreground, background); 46 | SDL_Rect textLocation = { 0 + camera.x, 0 + camera.y + debug_line_num * 25, len, 25 }; 47 | SDL_Texture *text = SDL_CreateTextureFromSurface(renderer, textSurface); 48 | renderToBuffer(renderer, text, NULL, &textLocation); 49 | 50 | debug_line_num++; 51 | } 52 | 53 | void draw(int deltaTimeMs) 54 | { 55 | float deltaTimeS = (float) deltaTimeMs / 1000; 56 | float fps = (float) 1.0 / deltaTimeS; 57 | 58 | debug_line_num = 0; 59 | 60 | renderToBuffer(renderer, map_tex, NULL, &map_rect); 61 | 62 | for (int i = 0; i < MAX_ENTITIES; i++) { 63 | if (entities[i] != NULL) 64 | renderEntity(renderer, entities[i], (int[3])WORLD_COLOR_HARD); 65 | } 66 | 67 | char str[10]; 68 | sprintf(str, "%3.2f fps", fps); 69 | draw_debug_line(str, 50); 70 | 71 | sprintf(str, "x: %d y: %d", mouse_x, mouse_y); 72 | draw_debug_line(str, 80); 73 | 74 | sprintf(str, "px: %2.0f py: %2.0f", character->x, character->y); 75 | draw_debug_line(str, 80); 76 | 77 | sprintf(str, "angle: %3.4f", character->torso_angle); 78 | draw_debug_line(str, 100); 79 | 80 | sprintf(str, "cx: %d cy: %d", camera.x, camera.y); 81 | draw_debug_line(str, 80); 82 | 83 | sprintf(str, "mx: %d my: %d", map_rect.x, map_rect.y); 84 | draw_debug_line(str, 80); 85 | 86 | sprintf(str, "dx: %3.1f dy: %3.1f", deltaX, deltaY); 87 | draw_debug_line(str, 100); 88 | 89 | double x = character->x + 32; 90 | double y = character->y + 32; 91 | SDL_RenderDrawLine(renderer, x, y, mouse_x, mouse_y); 92 | SDL_RenderDrawLine(renderer, x, y, mouse_x, y); 93 | SDL_RenderDrawLine(renderer, mouse_x, y, mouse_x, mouse_y); 94 | SDL_RenderDrawLine(renderer, x, y, x, mouse_y); 95 | SDL_RenderDrawLine(renderer, x, mouse_y, mouse_x, mouse_y); 96 | } 97 | 98 | void update(int deltaTimeMs) 99 | { 100 | float deltaTimeS = (float) deltaTimeMs / 1000; 101 | for (int i = 0; i < MAX_ENTITIES; i++) { 102 | if (entities[i] != NULL) 103 | updateEntity(entities[i], deltaTimeS); 104 | } 105 | updateCamera(); 106 | } 107 | 108 | void event(SDL_Event e, int deltaTimeMs) 109 | { 110 | if (e.type == SDL_KEYDOWN) { 111 | SDL_Scancode key = e.key.keysym.scancode; 112 | if (key == SDL_SCANCODE_SPACE) { 113 | toggleMusic(); 114 | } else if (key == SDL_SCANCODE_C) { 115 | if (curr_buffer == buffer) curr_buffer = collision_buffer; 116 | else curr_buffer = buffer; 117 | } else if (key == SDL_SCANCODE_E) { 118 | character->torso_angle += 5; 119 | if (character->torso_angle > 360) { 120 | character->torso_angle = 0; 121 | } 122 | } else if (key == SDL_SCANCODE_Q) { 123 | character->torso_angle -= 5; 124 | if (character->torso_angle < 0) { 125 | character->torso_angle = 360; 126 | } 127 | } 128 | } else if (e.type == SDL_MOUSEMOTION) { 129 | mouse_x = e.motion.x + camera.x; 130 | mouse_y = e.motion.y + camera.y; 131 | 132 | deltaX = mouse_x - character->x - character->w/2; 133 | deltaY = mouse_y - character->y - character->h/2; 134 | 135 | double rad = atan2(deltaY, deltaX); 136 | if (rad < 0) { 137 | rad += 2*PI; 138 | } 139 | character->torso_angle = 90 + (rad * 360 / 2*PI) / 10; 140 | } 141 | eventEntity(character, e, (float) deltaTimeMs / 1000); 142 | } 143 | 144 | int main(int argc, char **argv) 145 | { 146 | 147 | if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { 148 | fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError()); 149 | return 1; 150 | } 151 | if (TTF_Init() != 0) { 152 | fprintf(stderr, "Failed to initialize TTF: %s\n", SDL_GetError()); 153 | return 1; 154 | } 155 | if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096)) { 156 | fprintf(stderr, "Failed to load Mixer: %s", SDL_GetError()); 157 | } 158 | int imgFlags = IMG_INIT_JPG|IMG_INIT_PNG; 159 | if(!(IMG_Init(imgFlags) & imgFlags)) { 160 | fprintf(stderr,"Failed to initialize Image: %s",SDL_GetError()); 161 | } 162 | 163 | screen = SDL_CreateWindow(WINDOW_TITLE, 164 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 165 | WINDOW_WIDTH, WINDOW_HEIGHT, 166 | SDL_WINDOW_BORDERLESS); 167 | if (screen == NULL) { 168 | fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); 169 | return 1; 170 | } 171 | 172 | renderer = SDL_CreateRenderer(screen, -1, 0); 173 | if (renderer == NULL) { 174 | fprintf(stderr, "Failed to create renderer: %s\n", SDL_GetError()); 175 | return 1; 176 | } 177 | 178 | char* path = buildPath(ASSETS,"fonts/FONT.TTF"); 179 | font = TTF_OpenFont(path, 12); 180 | if (font == NULL) { 181 | fprintf(stderr, "Failed to load font: %s\n",TTF_GetError()); 182 | return 1; 183 | } 184 | free(path); 185 | 186 | /*Mix_Music* music = loadMusic(buildPath(ASSETS,"music/song.mp3"));*/ 187 | /*playMusic(music);*/ 188 | 189 | // Black backround 190 | SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 191 | 192 | game_init(); 193 | 194 | if (buffers_init(renderer) != 0) { 195 | fprintf(stderr, "Failed to craete buffers: %s", SDL_GetError()); 196 | return 1; 197 | } 198 | 199 | curr_buffer = buffer; 200 | SDL_Event e; 201 | SDL_Rect render_rect; 202 | render_rect.x = 0; 203 | render_rect.y = 0; 204 | render_rect.w = WINDOW_WIDTH; 205 | render_rect.h = WINDOW_HEIGHT; 206 | bool quit = false; 207 | int deltaTime = 0; 208 | int currentFrame = SDL_GetTicks(); 209 | int lastFrame; 210 | int fpsMs = 1000 / MAX_FPS; 211 | 212 | map_tex = renderMap(renderer, map); 213 | 214 | camera.x = 0; 215 | camera.y = 0; 216 | camera.w = WINDOW_WIDTH; 217 | camera.h = WINDOW_HEIGHT; 218 | 219 | while (!quit) { 220 | lastFrame = currentFrame; 221 | currentFrame = SDL_GetTicks(); 222 | deltaTime = currentFrame - lastFrame; 223 | renderClear(renderer); 224 | 225 | update(deltaTime); 226 | draw(deltaTime); 227 | 228 | while (SDL_PollEvent(&e)) { 229 | if (e.type == SDL_QUIT) 230 | quit = true; 231 | else 232 | event(e, deltaTime); 233 | } 234 | 235 | // Reset the target 236 | SDL_SetRenderTarget(renderer, NULL); 237 | // Copy the buffer 238 | SDL_RenderCopy(renderer, curr_buffer, &camera, &render_rect); 239 | // Draw the buffer to window 240 | SDL_RenderPresent(renderer); 241 | 242 | // Delay if we are drawing more that 100 fps 243 | float delay = fpsMs - deltaTime / 1000; 244 | if (delay > 0) SDL_Delay(delay); 245 | } 246 | 247 | SDL_Quit(); 248 | return 0; 249 | } 250 | -------------------------------------------------------------------------------- /src/music.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Mix_Music * loadMusic(char path[]) 7 | { 8 | Mix_Music * music = Mix_LoadMUS(path); 9 | 10 | if (music == NULL) { 11 | errx(1, "Failed to load music\nSDL ERROR: %s", SDL_GetError()); 12 | } 13 | 14 | return music; 15 | } 16 | 17 | void playMusic(Mix_Music * music) 18 | { 19 | Mix_PlayMusic(music, 1); 20 | } 21 | 22 | void toggleMusic() 23 | { 24 | if(Mix_PausedMusic()) { 25 | Mix_ResumeMusic(); 26 | } else { 27 | Mix_PauseMusic(); 28 | } 29 | } 30 | 31 | void cleanUp(Mix_Music * music) 32 | { 33 | Mix_FreeMusic(music); 34 | Mix_CloseAudio(); 35 | SDL_Quit(); 36 | } 37 | -------------------------------------------------------------------------------- /src/music.h: -------------------------------------------------------------------------------- 1 | #ifndef MUSIC 2 | #define MUSIC 3 | 4 | Mix_Music * loadMusic(char path[]); 5 | void playMusic(); 6 | void cleanUp(); 7 | void toggleMusic(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/render.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "render.h" 4 | #include "game.h" 5 | #include "collision.h" 6 | 7 | int rmask = 0xff000000; 8 | int gmask = 0x00ff0000; 9 | int bmask = 0x0000ff00; 10 | int amask = 0x000000ff; 11 | 12 | SDL_Texture* renderWeaponToTexture(SDL_Renderer *ren, heldWeapon *weapon_src, 13 | SDL_Texture *target_tex, SDL_Rect *target_src) 14 | { 15 | 16 | SDL_Texture *t = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 17 | target_src->w, target_src->h); 18 | 19 | 20 | SDL_SetTextureBlendMode(t, SDL_BLENDMODE_BLEND); 21 | 22 | if (SDL_SetRenderTarget(ren, t) != 0) { 23 | puts("FUCK RENDERWEAPON"); 24 | } 25 | SDL_SetRenderDrawColor(ren, 255, 255, 255, 0); 26 | 27 | SDL_RenderFillRect(ren, NULL); 28 | 29 | SDL_Rect dst = {0,0,target_src->w,target_src->h}; 30 | SDL_RenderCopy(ren, target_tex, target_src, &dst); 31 | dst.x += weapon_src->x_offset; 32 | dst.y += weapon_src->y_offset; 33 | SDL_RenderCopy(ren, TextureWeapons, &weapon_src->src, &dst); 34 | 35 | if (SDL_SetRenderTarget(ren, buffer) != 0) { 36 | puts("FUCK RENDERWEAPON2"); 37 | } 38 | 39 | return t; 40 | } 41 | 42 | void renderClear(SDL_Renderer *ren) 43 | { 44 | // Clear buffer 45 | setTargetToBuffer(ren); 46 | SDL_RenderClear(ren); 47 | 48 | // Clear collision buffer 49 | setTargetToCollisionBuffer(ren); 50 | SDL_RenderClear(ren); 51 | 52 | // Draw map collsion buffer to collision buffer 53 | SDL_RenderCopy(ren, map_collision_buffer, NULL, NULL); 54 | } 55 | 56 | void setColor(SDL_Renderer *ren, int color) 57 | { 58 | unsigned char r, g, b; 59 | 60 | r = (color >> 16) & 0xFF; 61 | g = (color >> 8) & 0xFF; 62 | b = (color) & 0xFF; 63 | 64 | SDL_SetRenderDrawColor(ren, r, g, b, SDL_ALPHA_OPAQUE); 65 | } 66 | 67 | void renderEntity(SDL_Renderer *ren, entity* e, int color[3]) 68 | { 69 | SDL_Rect *legsRect = &e->legs.frames[e->legs.currentFrame]; 70 | SDL_Rect *torsoRect = &e->torso; 71 | SDL_Rect bodyRect; 72 | 73 | bodyRect.x = e->x - map_rect.x; 74 | bodyRect.y = e->y - map_rect.y; 75 | bodyRect.w = e->w; 76 | bodyRect.h = e->h; 77 | SDL_Rect dstrect; 78 | dstrect.x = e->x; 79 | dstrect.y = e->y; 80 | 81 | // Legs 82 | dstrect.w = legsRect->w; 83 | dstrect.h = legsRect->h; 84 | renderToBufferEx(ren, e->legs.tex, legsRect, &dstrect, 85 | e->legs_angle, NULL); 86 | 87 | // Torso 88 | dstrect.w = torsoRect->w; 89 | dstrect.h = torsoRect->h; 90 | renderToBufferEx(ren, e->torso_tex, torsoRect, &dstrect, 91 | e->torso_angle, &e->torso_center); 92 | 93 | renderToCollisionBuffer(ren, NULL, &bodyRect, color); 94 | } 95 | 96 | void render(SDL_Renderer *ren, SDL_Texture *tex, SDL_Rect *srcrect, 97 | SDL_Rect *dstrect, int color[3]) 98 | { 99 | // NOTE: This doesn't take into account the map's position 100 | // (see renderEntity) 101 | renderToBuffer(ren, tex, srcrect, dstrect); 102 | renderToCollisionBuffer(ren, srcrect, dstrect, color); 103 | } 104 | 105 | void renderToBufferEx(SDL_Renderer *ren, SDL_Texture *tex, SDL_Rect *srcrect, 106 | SDL_Rect *dstrect, double angle, SDL_Point *point) 107 | { 108 | if (SDL_SetRenderTarget(ren, buffer) != 0) { 109 | puts("FUCK BUFFER"); 110 | } 111 | SDL_RenderCopyEx(ren, tex, srcrect, dstrect, angle, point, SDL_FLIP_NONE); 112 | } 113 | 114 | void renderToBuffer(SDL_Renderer *ren, SDL_Texture *tex, SDL_Rect *srcrect, 115 | SDL_Rect *dstrect) 116 | { 117 | if (SDL_SetRenderTarget(ren, buffer) != 0) { 118 | puts("FUCK BUFFER"); 119 | } 120 | SDL_RenderCopy(ren, tex, srcrect, dstrect); 121 | } 122 | 123 | void renderToCollisionBuffer(SDL_Renderer *ren, SDL_Rect *srcrect, 124 | SDL_Rect *dstrect, int color[3]) 125 | { 126 | if (SDL_SetRenderTarget(ren, collision_buffer) != 0) { 127 | puts("FUCK COLLISION"); 128 | } 129 | SDL_Texture *t = fillRect(ren, dstrect, color); 130 | SDL_RenderCopy(ren, t, srcrect, dstrect); 131 | } 132 | 133 | SDL_Texture* fillRect(SDL_Renderer *ren, SDL_Rect *rect, int color[3]) 134 | { 135 | SDL_Texture *t; 136 | SDL_Surface *s; 137 | 138 | s = SDL_CreateRGBSurface(0, rect->w, rect->h, 32, rmask, gmask, bmask, amask); 139 | SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 140 | color[0], color[1], color[2])); 141 | if (s == NULL) printf("FUCK SURFACE %s", SDL_GetError()); 142 | 143 | t = SDL_CreateTextureFromSurface(ren, s); 144 | 145 | return t; 146 | } 147 | 148 | int buffers_init(SDL_Renderer *ren) 149 | { 150 | buffer = NULL; 151 | collision_buffer = NULL; 152 | buffer = SDL_CreateTexture(ren, 0, 153 | SDL_TEXTUREACCESS_TARGET, map_rect.w, map_rect.h); 154 | 155 | 156 | collision_buffer = SDL_CreateTexture(ren, 0, 157 | SDL_TEXTUREACCESS_TARGET, map_rect.w, map_rect.h); 158 | 159 | 160 | 161 | map_collision_buffer = SDL_CreateTexture(ren, 0, 162 | SDL_TEXTUREACCESS_TARGET, map_rect.w, map_rect.h); 163 | 164 | 165 | if (buffer == NULL || collision_buffer == NULL 166 | || map_collision_buffer == NULL) 167 | return 1; 168 | 169 | return 0; 170 | } 171 | 172 | void setTargetToCollisionBuffer(SDL_Renderer *ren) 173 | { 174 | if (SDL_SetRenderTarget(ren, collision_buffer) != 0) { 175 | fprintf(stderr, "Failed to switch Target to collision_buffer"); 176 | } 177 | } 178 | 179 | void setTargetToBuffer(SDL_Renderer *ren) 180 | { 181 | if (SDL_SetRenderTarget(ren, buffer) != 0) { 182 | fprintf(stderr, "Failed to switch Target to buffer"); 183 | } 184 | } 185 | 186 | SDL_Texture* renderMap(SDL_Renderer *ren, tmx_map *map) 187 | { 188 | // Free and re-initialize the collision_map 189 | freeMapObjectArr(&collision_map); 190 | initMapObjectArr(&collision_map, 100); 191 | 192 | SDL_Texture *res; 193 | tmx_layer *layers = map->ly_head; 194 | int w, h; 195 | 196 | w = map->width * map->tile_width; 197 | h = map->height * map->tile_height; 198 | 199 | if (!(res = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, 200 | SDL_TEXTUREACCESS_TARGET, w, h))) 201 | puts("Error while creating map texture"); 202 | 203 | if (SDL_SetRenderTarget(ren, res) != 0) puts("FUCK TARGTE"); 204 | 205 | setColor(ren, map->backgroundcolor); 206 | SDL_RenderClear(ren); 207 | 208 | while (layers) { 209 | if (layers->visible) { 210 | if (layers->type == L_OBJGR) { 211 | drawObjects(ren, layers->content.head, layers->color); 212 | } else if (layers->type == L_IMAGE) { 213 | drawImageLayer(ren, layers->content.image); 214 | } else if (layers->type == L_LAYER) { 215 | drawLayer(ren, res, map, layers); 216 | } 217 | } 218 | layers = layers->next; 219 | } 220 | 221 | return res; 222 | } 223 | 224 | void drawObjects(SDL_Renderer *ren, tmx_object *head, int color) 225 | { 226 | SDL_Rect rect; 227 | setColor(ren, color); 228 | /* FIXME line thickness */ 229 | while (head) { 230 | if (head->visible) { 231 | if (head->shape == S_SQUARE) { 232 | rect.x = head->x; 233 | rect.y = head->y; 234 | rect.w = head->width; 235 | rect.h = head->height; 236 | SDL_RenderDrawRect(ren, &rect); 237 | } else if (head->shape == S_POLYGON) { 238 | drawPolygon(ren, head->points, head->x, head->y, head->points_len); 239 | } else if (head->shape == S_POLYLINE) { 240 | drawPolyline(ren, head->points, head->x, head->y, head->points_len); 241 | } else if (head->shape == S_ELLIPSE) { 242 | /* FIXME: no function in SDL2 */ 243 | } 244 | } 245 | head = head->next; 246 | } 247 | } 248 | 249 | void drawPolyline(SDL_Renderer *ren, double **points, double x, double y, int pointsc) 250 | { 251 | int i; 252 | for (i=1; i 2) { 261 | SDL_RenderDrawLine(ren, x+points[0][0], y+points[0][1], x+points[pointsc-1][0], y+points[pointsc-1][1]); 262 | } 263 | } 264 | 265 | void drawLayer(SDL_Renderer *ren, SDL_Texture *res, tmx_map *map, tmx_layer *layer) 266 | { 267 | unsigned long i, j; 268 | tmx_tileset *ts; 269 | SDL_Texture *tex_ts; 270 | SDL_Rect srcrect, dstrect; 271 | 272 | // Clear the map collision buffer 273 | SDL_SetRenderTarget(ren, map_collision_buffer); 274 | SDL_RenderClear(ren); 275 | // Set the target back to map's texture 276 | SDL_SetRenderTarget(ren, res); 277 | 278 | for (i=0; iheight; i++) { 279 | for (j=0; jwidth; j++) { 280 | ts = tmx_get_tileset(map, layer->content.gids[(i*map->width)+j], 281 | // FIXME: This probably aint good way to go.. 282 | (unsigned int *)&(srcrect.x), 283 | (unsigned int *)&(srcrect.y)); 284 | if (ts) { 285 | /* TODO Opacity and Flips */ 286 | srcrect.w = dstrect.w = ts->tile_width; 287 | srcrect.h = dstrect.h = ts->tile_height; 288 | dstrect.x = j*ts->tile_width; 289 | dstrect.y = i*ts->tile_height; 290 | tex_ts = SDL_CreateTextureFromSurface(ren, (SDL_Surface*)ts->image->resource_image); 291 | SDL_RenderCopy(ren, tex_ts, &srcrect, &dstrect); 292 | SDL_DestroyTexture(tex_ts); 293 | 294 | // Following if statement checks which layer we are on 295 | if (strcmp(layer->name, "solid") == 0) { 296 | // While toe following checks which tile (id) we have 297 | // if ((layer->content.gids[(i*map->width)+j] & TMX_FLIP_BITS_REMOVAL) == 5) { 298 | 299 | // Add collision point to collision_map 300 | insertMapObjectArr(&collision_map, dstrect); 301 | 302 | SDL_Texture *tex = fillRect(ren, &dstrect, (int[3])WORLD_COLOR_HARD); 303 | 304 | SDL_SetRenderTarget(ren, map_collision_buffer); 305 | SDL_RenderCopy(ren, tex, NULL, &dstrect); 306 | 307 | SDL_SetRenderTarget(ren, res); 308 | SDL_DestroyTexture(tex); 309 | } 310 | } 311 | } 312 | } 313 | } 314 | 315 | void drawImageLayer(SDL_Renderer *ren, tmx_image *img) 316 | { 317 | SDL_Surface *bmp; 318 | SDL_Texture *tex; 319 | SDL_Rect dim; 320 | 321 | bmp = (SDL_Surface*) img->resource_image; 322 | 323 | dim.x = dim.y = 0; 324 | dim.w = bmp->w; 325 | dim.h = bmp->h; 326 | 327 | if ((tex = SDL_CreateTextureFromSurface(ren, bmp))) { 328 | SDL_RenderCopy(ren, tex, NULL, &dim); 329 | SDL_DestroyTexture(tex); 330 | } 331 | 332 | } 333 | 334 | void updateCamera() 335 | { 336 | // Move camera 337 | camera.x = character->x - WINDOW_WIDTH / 2 + character->w / 2; 338 | camera.y = character->y - WINDOW_HEIGHT / 2; 339 | 340 | // Keep it in bounds 341 | if (camera.x < 0) camera.x = 0; 342 | else if (camera.x > map_rect.w - WINDOW_WIDTH) 343 | camera.x = map_rect.w - WINDOW_WIDTH; 344 | if (camera.y < 0) camera.y = 0; 345 | else if (camera.y > map_rect.h - WINDOW_HEIGHT) 346 | camera.y = map_rect.h - WINDOW_HEIGHT; 347 | } 348 | -------------------------------------------------------------------------------- /src/render.h: -------------------------------------------------------------------------------- 1 | #ifndef RENDER_H 2 | #define RENDER_H 3 | 4 | #include 5 | #include 6 | #include "entity.h" 7 | 8 | #define WINDOW_WIDTH 640 9 | #define WINDOW_HEIGHT 480 10 | 11 | #define WORLD_COLOR_HARD { 0, 255, 0 } 12 | 13 | SDL_Rect camera; 14 | 15 | SDL_Texture *buffer; 16 | SDL_Texture *collision_buffer; 17 | SDL_Texture *map_collision_buffer; 18 | 19 | // 0 success value, negative on error 20 | int buffers_init(SDL_Renderer *ren); 21 | 22 | void setColor(SDL_Renderer*, int color); 23 | 24 | SDL_Texture* renderWeaponToTexture(SDL_Renderer *ren, heldWeapon *weapon_src, 25 | SDL_Texture *target_tex, SDL_Rect *target_src); 26 | 27 | void renderClear(SDL_Renderer*); 28 | void render(SDL_Renderer*, SDL_Texture*, SDL_Rect*, SDL_Rect*, int color[3]); 29 | void renderEntity(SDL_Renderer*, entity*, int color[3]); 30 | void renderToBuffer(SDL_Renderer*, SDL_Texture*, SDL_Rect*, SDL_Rect*); 31 | void renderToBufferEx(SDL_Renderer*, SDL_Texture*, SDL_Rect*, SDL_Rect*, 32 | double angle, SDL_Point *point); 33 | void renderToCollisionBuffer(SDL_Renderer*, SDL_Rect*, SDL_Rect*, int color[3]); 34 | 35 | SDL_Texture* fillRect(SDL_Renderer *ren, SDL_Rect *rect, int color[3]); 36 | 37 | // If occours any errors, prints to stderr 38 | void setTargetToCollisionBuffer(SDL_Renderer*); 39 | void setTargetToBuffer(SDL_Renderer*); 40 | 41 | SDL_Texture* renderMap(SDL_Renderer*, tmx_map*); 42 | 43 | void drawObjects(SDL_Renderer*, tmx_object*, int); 44 | void drawPolyline(SDL_Renderer *ren, double **points, double x, double y, int pointsc); 45 | void drawPolygon(SDL_Renderer *ren, double **points, double x, double y, int pointsc); 46 | void drawLayer(SDL_Renderer *ren, SDL_Texture *res, tmx_map *map, tmx_layer *layer); 47 | void drawImageLayer(SDL_Renderer *ren, tmx_image *img); 48 | 49 | void updateCamera(); 50 | 51 | #endif // RENDER_H 52 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "util.h" 5 | 6 | char* buildPath(char* root, char* path) 7 | { 8 | char* full = malloc(strlen(root) + strlen(path) + 1); 9 | strcpy(full, root); 10 | strcat(full, path); 11 | return full; 12 | } 13 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | char* buildPath(char* root, char* path); 5 | 6 | #endif 7 | --------------------------------------------------------------------------------