#include #include #include #include #include #include #include "structs.h" #include "format.h" #include "defs.h" #define DEBUG 1 #define MAP_WIDTH 25 #define MAP_HEIGHT 25 int original_width = 1000; int original_height = 480; int screen_width = 1000; int screen_height = 480; int game_running = 1; struct game game; int movement_speed = 10; double delta_time; double last_frame; // network TCPsocket server_socket; // Textures SDL_Texture *grass_texture; SDL_Texture *cobble_texture; SDL_Texture *lava_texture; // scene int objects_count = 0; struct object ** objects_map; SDL_mutex *objects_map_mutex; void prepare_scene(void) { SDL_SetRenderDrawColor(game.renderer, 0, 0, 0, 0); SDL_RenderClear(game.renderer); } void key(SDL_KeyboardEvent *event) { if (event->repeat != 0) return; if (event->keysym.scancode == SDL_SCANCODE_J) game.left = !game.left; if (event->keysym.scancode == SDL_SCANCODE_K) game.right = !game.right; if (event->keysym.scancode == SDL_SCANCODE_SPACE) game.jump = !game.jump; } void handle_input(void) { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) game_running = 0; } } SDL_Texture *load_texture(const char *path) { SDL_Texture *texture; SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", path); texture = IMG_LoadTexture(game.renderer, path); return texture; } void present_scene(void) { SDL_RenderPresent(game.renderer); } int new_key_position(void **map, int slots) { int slot = 0; if (slots <= 0) return slot; if (map == NULL) return slot; while (slot <= slots) { if (map[slots] == NULL) break; slot++; } return slot; } int handle_server(void *data) { int message[MAP_WIDTH*MAP_HEIGHT]; int recv_len = SDLNet_TCP_Recv(server_socket, message, sizeof(int)*MAP_WIDTH*MAP_HEIGHT); if (!recv_len) { fprintf(stderr, "Error: failed receiving message from server\n%s\n", SDLNet_GetError()); return MEMERR; } if (DEBUG) fprintf(stdout, "Notice: received '%d' bytes from server\n", recv_len); SDL_LockMutex(objects_map_mutex); int blocks_num = recv_len / sizeof(int); for (int y = 0; y < MAP_HEIGHT; y++) { for (int x = 0; x < MAP_WIDTH; x++) { int iter = (y*MAP_WIDTH)+x; int ret = handle_block_creation(iter, message[iter], &objects_map, &objects_count); if (ret == MEMERR) { fprintf(stderr, "Error: failed creating new block\n"); return MEMERR; } struct object *block = objects_map[iter]; block->x = x * block->resolution * block->scale; block->y = y * block->resolution * block->scale; } } SDL_UnlockMutex(objects_map_mutex); return 0; } int connect_to_server(void) { IPaddress ip; if (SDLNet_ResolveHost(&ip, SERVER_ADDR, SERVER_PORT) != 0) { fprintf(stderr, "Error: resolving host of server\n%s\n", SDLNet_GetError()); return -1; } server_socket = SDLNet_TCP_Open(&ip); if (!server_socket) { fprintf(stderr, "Error: failed opening socket to '%s' at '%d'\n%s\n", SERVER_ADDR, SERVER_PORT, SDLNet_GetError()); return -1; } SDL_CreateThread(handle_server, "server", NULL); return 0; } void catch_alarm(int sig) { exit(EXIT_FAILURE); } void handle_events() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_RESIZED) SDL_GetWindowSize(game.window, &screen_width, &screen_height); break; case SDL_QUIT: exit(EXIT_SUCCESS); break; } } } int main(int argc, char *argv[]) { signal(SIGINT, catch_alarm); if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "Error: could not initialize SDL\n%s\n", SDL_GetError()); return -1; } if (SDLNet_Init() != 0) { fprintf(stderr, "Error: could not initialize SDL net\n%s\n", SDL_GetError()); return -1; } game.window = SDL_CreateWindow("03-network", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, WINDOW_FLAGS); SDL_SetWindowResizable(game.window, 1); if (game.window == NULL) { fprintf(stderr, "Error: could not create window\n%s\n", SDL_GetError()); return -1; } game.renderer = SDL_CreateRenderer(game.window, -1, RENDERER_FLAGS); if (game.renderer == NULL) { fprintf(stderr, "Error: could not create renderer\n%s\n", SDL_GetError()); return -1; } // load textures grass_texture = load_texture("assets/floor/grass.png"); cobble_texture = load_texture("assets/floor/cobble.png"); lava_texture = load_texture("assets/floor/lava.png"); // create mutexes objects_map_mutex = SDL_CreateMutex(); if (connect_to_server() != 0) return -1; while (game_running) { prepare_scene(); handle_events(); int lock = SDL_TryLockMutex(objects_map_mutex); if (lock == 0) { for (int iter = 0; iter < objects_count; iter++) { struct object *object = objects_map[iter]; if (object == NULL) continue; object->x = object->x - (object->scale * object->resolution * (original_width - original_width)); object->y = object->y - (object->scale * object->resolution * (original_height - original_height)); draw_object(&game, object); } SDL_UnlockMutex(objects_map_mutex); } present_scene(); SDL_Delay(100); } SDL_DestroyWindow(game.window); SDL_Quit(); return 0; }