lav-sdl

SDL верзија програма Лавиринт
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 0e6f8fa0369d055b2a39a3b084b1f669d49d86f2
родитељ b5de147b723c119ad1433058563ff7d5f699a907
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Mon, 14 Aug 2023 22:27:01 +0200

Add animations, sprites...

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
AREADME | 33+++++++++++++++++++++++++++++++++
Al00.dat | 10++++++++++
Al01.dat | 13+++++++++++++
Mlav-sdl.c | 690+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mlav-sdl.do | 1+
Alavirint.dat | 13+++++++++++++
Asprites.png | 0
Ater16.png | 0
измењених датотека: 8, додавања: 695(+), брисања: 65(-)

diff --git a/README b/README @@ -0,0 +1,33 @@ +Lavirint +======== + +SDL maze solver + + +License +------- + +lav-sdl - SDL maze solver +Copyright (C) 2023 Strahinya Radich + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. + +--- + +Sprite sheet ter16.png created in GIMP using Terminus font 4.49.1, Copyright (C) +2020 Dimitar Toshkov Zhekov[1], licensed under SIL Open Font License 1.1. See +file OFL.TXT for more information. + + +[1]: http://terminus-font.sourceforge.net/ diff --git a/l00.dat b/l00.dat @@ -0,0 +1,10 @@ + 1 3 + 16 8 + 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 + 1 1 0 1 1 0 0 0 1 0 0 1 0 1 0 1 + 0 1 0 1 0 1 0 1 0 0 1 0 0 1 1 1 + 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 + 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 0 + 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 + 0 1 0 1 0 1 1 1 1 0 0 0 1 0 1 0 + 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 diff --git a/l01.dat b/l01.dat @@ -0,0 +1,13 @@ +1 1 +24 11 +0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 +1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 1 0 +0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 1 1 0 +0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 +0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 +0 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 +0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 +0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 +0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 +0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 +0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 diff --git a/lav-sdl.c b/lav-sdl.c @@ -6,15 +6,35 @@ #define _DEFAULT_SOURCE #define _XOPEN_SOURCE +#include <errno.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <SDL.h> - -#define PROGNAME "lav-sdl" -#define DEFAULT_WIDTH 800 -#define DEFAULT_HEIGHT 600 -#define WIN_TITLE "Lavirint (SDL version)" +#include <SDL_image.h> + +#define PROGNAME "lav-sdl" +#define DEFAULT_WIDTH 800 +#define DEFAULT_HEIGHT 600 +#define WIN_TITLE "Lavirint (SDL version)" +#define CELL_SIZE 32 +#define LABYRINTH_MAXWIDTH 40 +#define LABYRINTH_MAXHEIGHT 20 +#define LOCATION_STACK_MAX (LABYRINTH_MAXWIDTH * LABYRINTH_MAXHEIGHT) +#define SEARCHING_DELAY 10 +#define ANIM_STEPS 10 +#define ANIM_DELAY 1 +#define TER16_WIDTH 8 +#define TER16_HEIGHT 17 + +#define EPS 1e-15 +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +enum { CELL_EMPTY, CELL_WALL, CELL_FAIL, CELL_OK, CELL_HERO }; +enum { STATE_SEARCHING, STATE_SEARCHING_PAUSED, STATE_FAILURE, STATE_SUCCESS }; + +const char* state_descriptions[] = {"Searching for exit", + "Searching for exit (paused)", "Failed!", "Success!"}; struct Labyrinth { char** cells; @@ -22,18 +42,33 @@ struct Labyrinth { int height; }; -static int running = 1; -static int redraw = 1; -static int screen_width = DEFAULT_WIDTH; -static int screen_height = DEFAULT_HEIGHT; -static SDL_Window* window = NULL; -static SDL_Renderer* renderer = NULL; +struct AnimationState { + SDL_FPoint position; + SDL_FPoint destination; + SDL_FPoint delta; + int active; + int step; + int final_step; +}; + +static int running = 1; +static int redraw = 1; +static int state = STATE_SEARCHING_PAUSED; +static int screen_width = DEFAULT_WIDTH; +static int screen_height = DEFAULT_HEIGHT; +static float scale_factor = 1.0f; +static SDL_Window* window = NULL; +static SDL_Renderer* renderer = NULL; +static SDL_Texture* sprites = NULL; +static SDL_Texture* ter16_texture = NULL; static struct Labyrinth labyrinth; +static SDL_Point hero, start, end; +static SDL_Point* location_stack = NULL; +static int location_pointer = 0; +static struct AnimationState animation; #define PRINT_BUFSIZE 4096 - -#define CELL_EMPTY 0 -#define CELL_WALL 1 +#define LOAD_BUFSIZE 4096 void print_debug(const char* fmt, ...) @@ -62,54 +97,449 @@ print_error(const char* fmt, ...) void cleanup(void) { - for (int y = 0; y < labyrinth.height; y++) + free(location_stack); + + for (int y = 0; y < LABYRINTH_MAXHEIGHT; y++) free(labyrinth.cells[y]); free(labyrinth.cells); + + if (ter16_texture) + SDL_DestroyTexture(ter16_texture); + if (sprites) + SDL_DestroyTexture(sprites); + if (renderer) + SDL_DestroyRenderer(renderer); + if (window) + SDL_DestroyWindow(window); SDL_Quit(); } void +draw_text(const int x, const int y, const int font_width, const int font_height, + SDL_Texture* font_tex, const char* text, ...) +{ + char buf[PRINT_BUFSIZE]; + va_list args; + const char* pbuf = NULL; + int xstart = 0; + int ystart = 0; + SDL_Rect source_rect; + SDL_FRect dest_rect; + int index = 0; + int chars_per_row = 0; + char first_char = ' '; + char last_char = '~'; + int tex_w, tex_h; + + if (!text || !font_tex) + return; + + va_start(args, text); + vsnprintf(buf, sizeof(buf), text, args); + va_end(args); + + source_rect.w = font_width; + source_rect.h = font_height; + + dest_rect.x = x; + dest_rect.y = y; + dest_rect.w = font_width * scale_factor; + dest_rect.h = font_height * scale_factor; + + if (SDL_QueryTexture(font_tex, NULL, NULL, &tex_w, &tex_h) < 0) + { + print_error("SDL_QueryTexture failed: %s", SDL_GetError()); + exit(1); + } + + chars_per_row = tex_w / (font_width + 1); + + pbuf = buf; + while (*pbuf) + { + if (*pbuf >= first_char && *pbuf <= last_char) + { + index = (int)(*pbuf - first_char); + + xstart = 1 + index % chars_per_row * (font_width + 1); + ystart = 1 + index / chars_per_row * (font_height + 1); + } + else + break; + + source_rect.x = xstart; + source_rect.y = ystart; + + SDL_RenderCopyF(renderer, font_tex, &source_rect, &dest_rect); + + dest_rect.x += font_width * scale_factor; + + pbuf++; + } +} + +void update_size(void) { SDL_GetWindowSize(window, &screen_width, &screen_height); + scale_factor = MIN((float)screen_width / DEFAULT_WIDTH, + (float)screen_height / DEFAULT_HEIGHT); +} + +void +labyrinth_coord_to_screen_coord(const int x, const int y, float* to_x, + float* to_y) +{ + int cx = screen_width / 2, cy = screen_height / 2; + + *to_x = cx - labyrinth.width / 2 * CELL_SIZE * scale_factor + + x * CELL_SIZE * scale_factor; + *to_y = cy - labyrinth.height / 2 * CELL_SIZE * scale_factor + + y * CELL_SIZE * scale_factor; +} + +void +labyrinth_coord_to_screen_coordF(const float x, const float y, float* to_x, + float* to_y) +{ + int cx = screen_width / 2, cy = screen_height / 2; + + *to_x = cx - labyrinth.width / 2 * CELL_SIZE * scale_factor + + x * CELL_SIZE * scale_factor; + *to_y = cy - labyrinth.height / 2 * CELL_SIZE * scale_factor + + y * CELL_SIZE * scale_factor; +} + +void +assign_point(const SDL_Point* from, SDL_Point* to) +{ + to->x = from->x; + to->y = from->y; +} + +void +assign_point_xy(const int x, const int y, SDL_Point* to) +{ + to->x = x; + to->y = y; +} + +void +assign_pointF(const SDL_FPoint* from, SDL_FPoint* to) +{ + to->x = from->x; + to->y = from->y; +} + +void +assign_point_xyF(const float x, const float y, SDL_FPoint* to) +{ + to->x = x; + to->y = y; +} + +void +assign_pointIF(const SDL_Point* from, SDL_FPoint* to) +{ + to->x = (float)from->x; + to->y = (float)from->y; +} + +void +assign_point_xyIF(const int x, const int y, SDL_FPoint* to) +{ + to->x = (float)x; + to->y = (float)y; +} + +void +calculate_delta(void) +{ + animation.delta.x + = fabsf(animation.destination.x - animation.position.x) + / ANIM_STEPS; + if (animation.destination.x < animation.position.x) + animation.delta.x *= -1; + animation.delta.y + = fabsf(animation.destination.y - animation.position.y) + / ANIM_STEPS; + if (animation.destination.y < animation.position.y) + animation.delta.y *= -1; +} + +void +load_textures(void) +{ + SDL_Surface* surface = NULL; + + surface = IMG_Load("sprites.png"); + if (!surface) + { + print_error("IMG_Load failed: %s", IMG_GetError()); + exit(1); + } + + sprites = SDL_CreateTextureFromSurface(renderer, surface); + if (!sprites) + { + print_error("SDL_CreateTextureFromSurface failed: %s", + SDL_GetError()); + exit(1); + } + SDL_FreeSurface(surface); + surface = NULL; + + surface = IMG_Load("ter16.png"); + if (!surface) + { + print_error("IMG_Load failed: %s", IMG_GetError()); + exit(1); + } + + ter16_texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!ter16_texture) + { + print_error("SDL_CreateTextureFromSurface failed: %s", + SDL_GetError()); + exit(1); + } + + SDL_FreeSurface(surface); +} + +void +load_labyrinth(const char* pathname) +{ + FILE* input = NULL; + int x, y; + int firstline = 1; + + input = fopen(pathname, "rt"); + if (!input) + { + print_error("load_labyrinth: fopen failed: %s (%s)", + strerror(errno), pathname); + exit(1); + } + + labyrinth.cells = (char**)calloc(LABYRINTH_MAXHEIGHT, sizeof(char*)); + if (!labyrinth.cells) + { + print_error("calloc failed"); + exit(1); + } + for (y = 0; y < LABYRINTH_MAXHEIGHT; y++) + { + labyrinth.cells[y] = (char*)calloc(LABYRINTH_MAXWIDTH, 1); + if (!labyrinth.cells[y]) + { + print_error("calloc failed"); + exit(1); + } + } + fscanf(input, "%d %d\n", &start.x, &start.y); + /* 1-based coordinates for compatibility */ + start.x--; + start.y--; + fscanf(input, "%d %d\n", &end.x, &end.y); + end.x--; + end.y--; + + x = 0; + y = 0; + labyrinth.width = 0; + labyrinth.height = 0; + while (!feof(input)) + { + char ch = fgetc(input); + if (ch == EOF) + continue; + + if (ch == '1') + { + labyrinth.cells[y][x] = CELL_WALL; + x++; + if (firstline) + labyrinth.width++; + } + else if (ch == '0') + { + labyrinth.cells[y][x] = CELL_EMPTY; + x++; + if (firstline) + labyrinth.width++; + } + else if (ch == '\n') + { + x = 0; + y++; + firstline = 0; + labyrinth.height++; + } + else if (strchr(" \r", ch)) + /* Ignore CR for compatibility */; + else + print_debug("Unknown character in labyrinth file: '%c'" + " = %X", + ch, ch); + + if (x == LABYRINTH_MAXWIDTH) + { + x = 0; + y++; + firstline = 0; + labyrinth.height++; + } + if (y == LABYRINTH_MAXHEIGHT) + { + print_error("Labyrinth overflow"); + exit(1); + } + } + + hero.x = start.x; + hero.y = start.y; + labyrinth.cells[hero.y][hero.x] = CELL_HERO; + + fclose(input); +} + +void +reset() +{ + for (int y = 0; y < labyrinth.height; y++) + for (int x = 0; x < labyrinth.width; x++) + if (labyrinth.cells[y][x] == CELL_FAIL + || labyrinth.cells[y][x] == CELL_OK + || labyrinth.cells[y][x] == CELL_HERO) + labyrinth.cells[y][x] = CELL_EMPTY; + hero.x = start.x; + hero.y = start.y; + labyrinth.cells[hero.y][hero.x] = CELL_HERO; + state = STATE_SEARCHING_PAUSED; + location_pointer = 0; + redraw = 1; +} + +void +get_sprite_xy(const char cell, int* x, int* y) +{ + switch (cell) + { + case CELL_WALL: + *x = 1; + *y = 1; + break; + case CELL_FAIL: + *x = 1 + 1 * (CELL_SIZE + 1); + *y = 1; + break; + case CELL_OK: + *x = 1 + 2 * (CELL_SIZE + 1); + *y = 1; + break; + case CELL_HERO: + switch (state) + { + case STATE_SUCCESS: + *x = 1 + 4 * (CELL_SIZE + 1); + *y = 1; + break; + case STATE_FAILURE: + *x = 1 + 6 * (CELL_SIZE + 1); + *y = 1; + break; + default: + *x = 1 + 3 * (CELL_SIZE + 1); + *y = 1; + break; + } + break; + default: + *x = 1 + 5 * (CELL_SIZE + 1); + *y = 1; + } } void draw(void) { - SDL_Rect rect; + SDL_Rect bg_rect, cell_rect; + SDL_FRect dest_rect; int x, y; int cx = screen_width / 2, cy = screen_height / 2; - int cell_size = 30; SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderClear(renderer); - rect.w = cell_size; - rect.h = cell_size; + bg_rect.x = cx - labyrinth.width / 2 * CELL_SIZE * scale_factor; + bg_rect.y = cy - labyrinth.height / 2 * CELL_SIZE * scale_factor; + bg_rect.w = CELL_SIZE * scale_factor * labyrinth.width; + bg_rect.h = CELL_SIZE * scale_factor * labyrinth.height; + SDL_SetRenderDrawColor(renderer, 0x22, 0x22, 0x22, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(renderer, &bg_rect); + + cell_rect.w = CELL_SIZE; + cell_rect.h = CELL_SIZE; + + dest_rect.w = CELL_SIZE * scale_factor; + dest_rect.h = CELL_SIZE * scale_factor; for (y = 0; y < labyrinth.height; y++) for (x = 0; x < labyrinth.width; x++) { - rect.x = cx - labyrinth.width / 2 * cell_size - + x * cell_size; - rect.y = cy - labyrinth.height / 2 * cell_size - + y * cell_size; - - switch (labyrinth.cells[y][x]) + if (x == start.x && y == start.y + && (animation.active || hero.x != x + || hero.y != y)) + { + cell_rect.x = 1 + 8 * (CELL_SIZE + 1); + cell_rect.y = 1; + } + else if (x == end.x && y == end.y + && (animation.active || hero.x != x + || hero.y != y)) { - case CELL_WALL: - SDL_SetRenderDrawColor(renderer, 128, 128, 128, - SDL_ALPHA_OPAQUE); - break; - default: - SDL_SetRenderDrawColor(renderer, 20, 20, 20, - SDL_ALPHA_OPAQUE); - break; + cell_rect.x = 1 + 7 * (CELL_SIZE + 1); + cell_rect.y = 1; } - SDL_RenderFillRect(renderer, &rect); + else if (animation.active + && labyrinth.cells[y][x] == CELL_HERO) + get_sprite_xy(CELL_EMPTY, &cell_rect.x, + &cell_rect.y); + else + get_sprite_xy(labyrinth.cells[y][x], + &cell_rect.x, &cell_rect.y); + labyrinth_coord_to_screen_coord(x, y, &dest_rect.x, + &dest_rect.y); + SDL_RenderCopyF(renderer, sprites, &cell_rect, + &dest_rect); } + draw_text(bg_rect.x, bg_rect.y + bg_rect.h, TER16_WIDTH, TER16_HEIGHT, + ter16_texture, "Column: %2d, Row: %2d", hero.x + 1, + hero.y + 1); + draw_text(cx - 30 * (TER16_WIDTH + 1), bg_rect.y + bg_rect.h, + TER16_WIDTH, TER16_HEIGHT, ter16_texture, "Status: %s", + state_descriptions[state]); + + if (animation.active) + { + labyrinth_coord_to_screen_coordF(animation.position.x, + animation.position.y, &dest_rect.x, &dest_rect.y); + get_sprite_xy((const char)CELL_HERO, &cell_rect.x, &cell_rect.y); + SDL_RenderCopyF(renderer, sprites, &cell_rect, &dest_rect); + animation.position.x += animation.delta.x; + animation.position.y += animation.delta.y; + animation.step++; + if (animation.step == animation.final_step) + { + animation.active = 0; + hero.x = (int)animation.destination.x; + hero.y = (int)animation.destination.y; + labyrinth.cells[hero.y][hero.x] = CELL_HERO; + } + } + SDL_RenderPresent(renderer); // SDL_RenderFlush(renderer); } @@ -128,6 +558,8 @@ handle_event(SDL_Event* event) { case SDL_WINDOWEVENT_RESIZED: update_size(); + print_debug("Got Resized, size: %d x %d, scale = %2.2f", + screen_width, screen_height, scale_factor); redraw = 1; break; } @@ -140,6 +572,24 @@ handle_event(SDL_Event* event) if (keysym.sym == SDLK_ESCAPE) running = 0; + else if (keysym.sym == SDLK_SPACE) + { + if (state == STATE_SEARCHING) + { + print_debug("State: paused"); + state = STATE_SEARCHING_PAUSED; + } + else if (state == STATE_SEARCHING_PAUSED) + { + print_debug("State: searching"); + state = STATE_SEARCHING; + } + else + { + print_debug("Resetting"); + reset(); + } + } else if (keysym.sym == SDLK_q && (keysym.mod & KMOD_CTRL)) running = 0; break; @@ -147,6 +597,126 @@ handle_event(SDL_Event* event) } int +passable(const int x, const int y) +{ + return (x >= 0 && x < labyrinth.width && y >= 0 && y < labyrinth.height + && labyrinth.cells[y][x] == CELL_EMPTY); +} + +void +location_push(const SDL_Point* location) +{ + location_stack[location_pointer].x = location->x; + location_stack[location_pointer].y = location->y; + location_pointer++; +} + +int +location_pop(SDL_Point* location) +{ + if (location_pointer == 0) + return 1; + location_pointer--; + location->x = location_stack[location_pointer].x; + location->y = location_stack[location_pointer].y; + return 0; +} + +void +next_step(void) +{ + SDL_Point backup; + + if (hero.x == end.x && hero.y == end.y) + { + print_debug("next_step: Success"); + state = STATE_SUCCESS; + } + else if (hero.x > 0 && passable(hero.x - 1, hero.y)) + { + print_debug("next_step: Trying x-1, y: (%d, %d), " + "pushed to stack (%d, %d)", + hero.x - 1, hero.y, hero.x, hero.y); + labyrinth.cells[hero.y][hero.x] = CELL_OK; + location_push(&hero); + assign_point_xyIF(hero.x, hero.y, &animation.position); + assign_point_xyIF(hero.x - 1, hero.y, &animation.destination); + calculate_delta(); + animation.step = 1; + animation.final_step = ANIM_STEPS; + animation.active = 1; + // labyrinth.cells[hero.y][hero.x] = CELL_HERO; + } + else if (hero.y > 0 && passable(hero.x, hero.y - 1)) + { + print_debug("next_step: Trying x, y-1: (%d, %d), " + "pushed to stack (%d, %d)", + hero.x, hero.y - 1, hero.x, hero.y); + labyrinth.cells[hero.y][hero.x] = CELL_OK; + location_push(&hero); + assign_point_xyIF(hero.x, hero.y, &animation.position); + assign_point_xyIF(hero.x, hero.y - 1, &animation.destination); + calculate_delta(); + animation.step = 1; + animation.final_step = ANIM_STEPS; + animation.active = 1; + // labyrinth.cells[hero.y][hero.x] = CELL_HERO; + } + else if (hero.x + 1 < labyrinth.width && passable(hero.x + 1, hero.y)) + { + print_debug("next_step: Trying x+1, y: (%d, %d), " + "pushed to stack (%d, %d)", + hero.x + 1, hero.y, hero.x, hero.y); + labyrinth.cells[hero.y][hero.x] = CELL_OK; + location_push(&hero); + assign_point_xyIF(hero.x, hero.y, &animation.position); + assign_point_xyIF(hero.x + 1, hero.y, &animation.destination); + calculate_delta(); + animation.step = 1; + animation.final_step = ANIM_STEPS; + animation.active = 1; + // labyrinth.cells[hero.y][hero.x] = CELL_HERO; + } + else if (hero.y + 1 < labyrinth.height && passable(hero.x, hero.y + 1)) + { + print_debug("next_step: Trying x, y+1: (%d, %d), " + "pushed to stack (%d, %d)", + hero.x, hero.y + 1, hero.x, hero.y); + labyrinth.cells[hero.y][hero.x] = CELL_OK; + location_push(&hero); + assign_point_xyIF(hero.x, hero.y, &animation.position); + assign_point_xyIF(hero.x, hero.y + 1, &animation.destination); + calculate_delta(); + animation.step = 1; + animation.final_step = ANIM_STEPS; + animation.active = 1; + // labyrinth.cells[hero.y][hero.x] = CELL_HERO; + } + else + { + /* Back up */ + if (location_pop(&backup)) + { + print_debug("State: failure"); + state = STATE_FAILURE; + } + else + { + print_debug("Backing up, stack pop: %d, %d", backup.x, + backup.y); + labyrinth.cells[hero.y][hero.x] = CELL_FAIL; + assign_pointIF(&hero, &animation.position); + assign_pointIF(&backup, &animation.destination); + calculate_delta(); + animation.step = 1; + animation.final_step = ANIM_STEPS; + animation.active = 1; + } + } + redraw = 1; +} + +int main(void) { SDL_Event event; @@ -173,46 +743,36 @@ main(void) SDL_SetWindowTitle(window, WIN_TITLE); SDL_RenderSetVSync(renderer, 1); - labyrinth.width = 10; - labyrinth.height = 10; - labyrinth.cells = (char**)calloc(labyrinth.height, sizeof(char*)); - if (!labyrinth.cells) - { - print_error("calloc failed"); - exit(1); - } - for (int y = 0; y < labyrinth.height; y++) - { - labyrinth.cells[y] = (char*)calloc(labyrinth.width, 1); - if (!labyrinth.cells[y]) - { - print_error("calloc failed"); - exit(1); - } - } - - labyrinth.cells[0][0] = CELL_WALL; - labyrinth.cells[0][1] = CELL_WALL; - labyrinth.cells[0][9] = CELL_WALL; - labyrinth.cells[1][2] = CELL_WALL; - labyrinth.cells[1][9] = CELL_WALL; - labyrinth.cells[9][0] = CELL_WALL; - labyrinth.cells[9][9] = CELL_WALL; - + load_textures(); + load_labyrinth("lavirint.dat"); + location_stack + = (SDL_Point*)calloc(LOCATION_STACK_MAX, sizeof(SDL_Point)); update_size(); + animation.active = 0; while (running) { while (SDL_PollEvent(&event)) handle_event(&event); - if (redraw) - { + if (animation.active) draw(); - redraw = 0; - } + else + { + if (state == STATE_SEARCHING) + { + next_step(); + SDL_Delay(SEARCHING_DELAY); + } - SDL_Delay(10); + if (redraw) + { + draw(); + redraw = 0; + } + + SDL_Delay(10); + } } return 0; diff --git a/lav-sdl.do b/lav-sdl.do @@ -1,4 +1,5 @@ redo-ifchange lav-sdl.o CFLAGS=${CFLAGS:- -Wall} LIBS=$(pkg-config --libs sdl2) +LIBS="$LIBS $(pkg-config --libs SDL2_image)" gcc $CFLAGS -o $3 lav-sdl.o $LIBS diff --git a/lavirint.dat b/lavirint.dat @@ -0,0 +1,13 @@ +1 1 +24 11 +0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 +1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 1 0 +0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 1 1 0 +0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 +0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 +0 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 +0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 +0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 +0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 +0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 +0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 diff --git a/sprites.png b/sprites.png Бинарне датотеке се разликују. diff --git a/ter16.png b/ter16.png Бинарне датотеке се разликују.