diff --git a/04-collision/client/README.md b/04-collision/client/README.md deleted file mode 100644 index 07cdb1d..0000000 --- a/04-collision/client/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Collision - Client - -Client-side code for 04-collision diff --git a/04-collision/client/assets/player/idle_down.png b/04-collision/client/assets/player/idle_down.png deleted file mode 100644 index 3241ca6..0000000 Binary files a/04-collision/client/assets/player/idle_down.png and /dev/null differ diff --git a/04-collision/client/assets/player/idle_left.png b/04-collision/client/assets/player/idle_left.png deleted file mode 100644 index 9f5e370..0000000 Binary files a/04-collision/client/assets/player/idle_left.png and /dev/null differ diff --git a/04-collision/client/assets/player/idle_right.png b/04-collision/client/assets/player/idle_right.png deleted file mode 100644 index 66a019b..0000000 Binary files a/04-collision/client/assets/player/idle_right.png and /dev/null differ diff --git a/04-collision/client/assets/player/idle_up.png b/04-collision/client/assets/player/idle_up.png deleted file mode 100644 index 8c3fd06..0000000 Binary files a/04-collision/client/assets/player/idle_up.png and /dev/null differ diff --git a/04-collision/client/assets/player/move_down.png b/04-collision/client/assets/player/move_down.png deleted file mode 100644 index 6d6e1e9..0000000 Binary files a/04-collision/client/assets/player/move_down.png and /dev/null differ diff --git a/04-collision/client/assets/player/move_left.png b/04-collision/client/assets/player/move_left.png deleted file mode 100644 index 9565034..0000000 Binary files a/04-collision/client/assets/player/move_left.png and /dev/null differ diff --git a/04-collision/client/assets/player/move_right.png b/04-collision/client/assets/player/move_right.png deleted file mode 100644 index 4c49d51..0000000 Binary files a/04-collision/client/assets/player/move_right.png and /dev/null differ diff --git a/04-collision/client/assets/player/move_up.png b/04-collision/client/assets/player/move_up.png deleted file mode 100644 index f702e80..0000000 Binary files a/04-collision/client/assets/player/move_up.png and /dev/null differ diff --git a/04-collision/client/assets/player/tilemap.png b/04-collision/client/assets/player/tilemap.png deleted file mode 100644 index 1f5af92..0000000 Binary files a/04-collision/client/assets/player/tilemap.png and /dev/null differ diff --git a/04-collision/client/src/format.c b/04-collision/client/src/format.c deleted file mode 100644 index afbe628..0000000 --- a/04-collision/client/src/format.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include "defs.h" -#include "structs.h" -#include "format.h" - -extern SDL_Texture *idle_down_animation; -extern struct object *create_object(SDL_Texture *texture, int scale, int resolution); - -int handle_player_connect(int *message, struct object ***map, int *slots) { - int object_id = message[1]; - - if (object_id >= *slots) { - *slots = object_id+1; - *map = realloc(*map, sizeof(struct object *)*(*slots)); - } - - if (*map == NULL) - return MEMERR; - - struct object *new_object = create_object(idle_down_animation, 4, 64); - if (new_object == NULL) - return MEMERR; - - new_object->id = object_id; - new_object->x = message[2]; - new_object->y = message[3]; - new_object->colliding = message[4]; - new_object->force = message[5]; - new_object->state = message[6]; - (*map)[object_id] = new_object; - - return STDOK; -} - -int handle_object_properties(int *message, struct object ***map, int *slots) { - int object_id = message[1]; - - if (object_id >= *slots) { - *slots = object_id+1; - *map = realloc(*map, sizeof(struct object *)*(*slots)); - } - - if (*map == NULL) - return MEMERR; - - if ((*map)[object_id] == NULL) { - struct object *new_object = create_object(idle_down_animation, 4, 64); - if (new_object == NULL) - return MEMERR; - - new_object->id = object_id; - (*map)[object_id] = new_object; - } - - (*map)[object_id]->x = message[2]; - (*map)[object_id]->y = message[3]; - (*map)[object_id]->colliding = message[4]; - (*map)[object_id]->force = message[5]; - (*map)[object_id]->state = message[6]; - - return STDOK; -} diff --git a/04-collision/client/src/format.h b/04-collision/client/src/format.h deleted file mode 100644 index f84065a..0000000 --- a/04-collision/client/src/format.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef FORMAT_H -#define FORMAT_H - -#include - -int handle_player_connect(int *message, struct object ***map, int *slots); -int handle_object_properties(int *message, struct object ***map, int *slots); - -#endif diff --git a/04-collision/client/src/main.c b/04-collision/client/src/main.c deleted file mode 100644 index 9914a22..0000000 --- a/04-collision/client/src/main.c +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include -#include -#include "structs.h" -#include "defs.h" -#include "format.h" - -#define DEBUG 1 - -int game_running = 1; -struct game game; -int movement_speed = 10; -double delta_time; -double last_frame; - -// network -TCPsocket server_socket; - -// textures -SDL_Texture *idle_animation; -SDL_Texture *move_left_animation; -SDL_Texture *move_right_animation; -SDL_Texture *move_up_animation; -SDL_Texture *move_down_animation; -SDL_Texture *idle_left_animation; -SDL_Texture *idle_right_animation; -SDL_Texture *idle_up_animation; -SDL_Texture *idle_down_animation; - -// scene -int objects_count = 0; -struct object ** objects_map; - -void prepare_scene(void) { - SDL_SetRenderDrawColor(game.renderer, 96, 128, 255, 255); - SDL_RenderClear(game.renderer); -} - -void key(SDL_KeyboardEvent *event) { - if (event->repeat != 0) - return; - - if (event->keysym.scancode == SDL_SCANCODE_D) - game.left = !game.left; - if (event->keysym.scancode == SDL_SCANCODE_F) - game.right = !game.right; - if (event->keysym.scancode == SDL_SCANCODE_K) - game.up = !game.up; - if (event->keysym.scancode == SDL_SCANCODE_J) - game.down = !game.down; -} - -void handle_input(void) { - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - game_running = 0; - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - key(&event.key); - break; - default: - break; - } - 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) { - for (;;) { - int message[CLIENT_MESSAGE_LEN]; - int recv_len = SDLNet_TCP_Recv(server_socket, message, sizeof(int)*CLIENT_MESSAGE_LEN); - - if (!recv_len) { - fprintf(stderr, "Error: failed receiving message from server\n%s\n", SDLNet_GetError()); - break; - } - - if (DEBUG) - fprintf(stdout, "Notice: received '%d' bytes from server\n", recv_len); - - if (message[0] == PLAYER_CONNECT_FORMAT) { - if (DEBUG) - fprintf(stdout, "DEBUG: PLAYER CONNECT MESSAGE\n"); - - int ret = handle_player_connect(message, &objects_map, &objects_count); - if (ret == MEMERR) { - fprintf(stderr, "MEMERR: Failed handling memory for player connect\n"); - return MEMERR; - } - - continue; - } - - if (message[0] == OBJECT_PROPERTIES_FORMAT) { - if (DEBUG) - fprintf(stdout, "DEBUG: OBJECT PROPERTIES MESSAGE FOR ID %d\n", message[1]); - - int ret = handle_object_properties(message, &objects_map, &objects_count); - if (ret == MEMERR) { - fprintf(stderr, "MEMERR: Failed handling memory for new object properties\n"); - return MEMERR; - } - - continue; - } - - if (message[0] == PLAYER_DISCONNECT_FORMAT) { - if (DEBUG) - fprintf(stdout, "DEBUG: PLAYER DISCONNECT MESSAGE\n"); - - int object_id = message[1]; - - free(objects_map[object_id]); - objects_map[object_id] = NULL; - - continue; - } - } - - 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; -} - -int main(int argc, char *argv[]) { - 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); - - 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 player animations - move_left_animation = load_texture("assets/player/move_left.png"); - move_right_animation = load_texture("assets/player/move_right.png"); - move_up_animation = load_texture("assets/player/move_up.png"); - move_down_animation = load_texture("assets/player/move_down.png"); - idle_left_animation = load_texture("assets/player/idle_left.png"); - idle_right_animation = load_texture("assets/player/idle_right.png"); - idle_up_animation = load_texture("assets/player/idle_up.png"); - idle_down_animation = load_texture("assets/player/idle_down.png"); - idle_animation = idle_down_animation; - - if (connect_to_server() != 0) - return -1; - - // game loop - while (game_running) { - double current_frame = SDL_GetTicks(); - delta_time = current_frame - last_frame; - last_frame = current_frame; - - prepare_scene(); - handle_input(); - - uint8_t message[SERVER_MESSAGE_LEN]; - message[0] = (game.left << 7) | - (game.right << 6) | - (game.up << 5) | - (game.down << 4); - - SDLNet_TCP_Send(server_socket, message, sizeof(uint8_t)*SERVER_MESSAGE_LEN); - - for (int iter = 0; iter < objects_count; iter++) { - struct object *obj = objects_map[iter]; - if (obj == NULL) - continue; - - if (obj->state & LEFT_MOVEMENT) { - switch_animation(obj, move_left_animation); - idle_animation = idle_left_animation; - } - - if (obj->state & RIGHT_MOVEMENT) { - switch_animation(obj, move_right_animation); - idle_animation = idle_right_animation; - } - - if (obj->state & UP_MOVEMENT) { - switch_animation(obj, move_up_animation); - idle_animation = idle_up_animation; - } - - if (obj->state & DOWN_MOVEMENT) { - switch_animation(obj, move_down_animation); - idle_animation = idle_down_animation; - } - - if (obj->state == NO_MOVEMENT) - switch_animation(obj, idle_animation); - - obj->animation_speed = 6; - - draw_object(&game, obj); - } - - present_scene(); - - SDL_Delay(16); - } - - SDL_DestroyWindow(game.window); - SDL_Quit(); - - return 0; -} diff --git a/04-collision/server/README.md b/04-collision/server/README.md deleted file mode 100644 index c3ea17a..0000000 --- a/04-collision/server/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Collision - Server - -Server-side code for 04-collision diff --git a/04-collision/server/src/main.c b/04-collision/server/src/main.c deleted file mode 100644 index 531f7f8..0000000 --- a/04-collision/server/src/main.c +++ /dev/null @@ -1,216 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "defs.h" -#include "structs.h" -#include "structures.h" - -#define DEBUG 0x0010 -#define PORT 9080 - -struct object **objects_map; -int objects_map_size = 0; -int objects_count = 0; - -struct connection **connections_map; -int connections_map_size = 0; -int connections_count = 0; - -void handle_player_input(struct object *obj, char *message) { - uint8_t action = message[0]; - - if (action & LEFT_MOVEMENT) - obj->x -= MOVEMENT_SPEED; - - if (action & RIGHT_MOVEMENT) - obj->x += MOVEMENT_SPEED; - - if (action & UP_MOVEMENT) - obj->y -= MOVEMENT_SPEED; - - if (action & DOWN_MOVEMENT) - obj->y += MOVEMENT_SPEED; - - obj->state = action; -} - -void handle_player_physics(struct object *obj) { -} - -int broadcast_event(int format, int object_id) { - struct object *obj = objects_map[object_id]; - - for (int iter = 0; iter < connections_map_size; iter++) { - struct connection *con = connections_map[iter]; - if (con == NULL) - continue; - - int message[] = { - format, - obj->id, - obj->x, - obj->y, - obj->colliding, - obj->force, - obj->state - }; - - SDLNet_TCP_Send(con->socket, message, sizeof(int)*CLIENT_MESSAGE_LEN); - } - - return 0; -} - -int handle_player(void *data) { - struct connection *connection_data = (struct connection *) data; - struct object *obj = objects_map[connection_data->obj_id]; - - SDLNet_SocketSet set = SDLNet_AllocSocketSet(1); - if (set == NULL) { - fprintf(stderr, "Error: cannot allocate memory for a new socket set\n"); - return -1; - } - - int ret = SDLNet_TCP_AddSocket(set, connection_data->socket); - if (ret == -1) { - fprintf(stderr, "Error: max socket count in socket set reached\n"); - return -1; - } - - broadcast_event(PLAYER_CONNECT_FORMAT, connection_data->obj_id); - - for (;;) { - char message[SERVER_MESSAGE_LEN]; - int ready_sockets = SDLNet_CheckSockets(set, 100); - if (ready_sockets == -1) { - fprintf(stderr, "Error: cannot call select() system call with SDLNet_CheckSockets()\n"); - continue; - } - - if (ready_sockets == 0) - goto update_client; - - int recv_len = SDLNet_TCP_Recv(connection_data->socket, message, SERVER_MESSAGE_LEN); - if (!recv_len) { - // player disconnected - fprintf(stderr, "Error: failed receiving message\n%s\n", SDLNet_GetError()); - break; - } - - if (DEBUG & GENERAL_DEBUG) - fprintf(stdout, "Notice: received '%s' and '%d' bytes\n", message, recv_len); - - handle_player_input(obj, message); - - update_client: - handle_player_physics(obj); - broadcast_event(OBJECT_PROPERTIES_FORMAT, connection_data->obj_id); - } - - // Communicate client disconnect - broadcast_event(PLAYER_DISCONNECT_FORMAT, connection_data->obj_id); - - SDLNet_FreeSocketSet(set); - SDLNet_TCP_Close(connection_data->socket); - - objects_map[connection_data->obj_id] = NULL; - objects_count--; - - connections_map[connection_data->id] = NULL; - connections_count--; - - free(obj); - free(data); - - return 0; -} - -void catch_alarm(int sig) { - fprintf(stdout, "Notice: force stopping server...\n"); - exit(EXIT_SUCCESS); -} - -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[slot] == NULL) - break; - - slot++; - } - - return slot; -} - -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; - } - - IPaddress ip; - if (SDLNet_ResolveHost(&ip, NULL, PORT) == -1) { - fprintf(stderr, "Error: failed resolving host \n%s\n", SDL_GetError()); - return -1; - } - - TCPsocket server = SDLNet_TCP_Open(&ip); - if (!server) { - fprintf(stderr, "Error: failed opening socket at %d\n%s\n", PORT, SDL_GetError()); - return -1; - } - - for (;;) { - TCPsocket client = SDLNet_TCP_Accept(server); - if (!client) { - SDL_Delay(100); - continue; - } - - fprintf(stdout, "Notice: accepted a connection from client!\n"); - - int new_object_slot = map_allocate_value((void ***) &objects_map, &objects_map_size, &objects_count, sizeof(struct object)); - if (new_object_slot == MEMERR) { - fprintf(stderr, "MEMERR: failed allocating memory for new object\n"); - return STDERR; - } - - int new_connection_slot = map_allocate_value((void ***) &connections_map, &connections_map_size, &connections_count, sizeof(struct connection)); - if (new_connection_slot == MEMERR) { - fprintf(stderr, "MEMERR: failed allocating memory for new connection\n"); - return STDERR; - } - - struct object *new_object = objects_map[new_object_slot]; - struct connection *new_connection = connections_map[new_connection_slot]; - - new_object->id = new_object_slot; - new_connection->id = new_connection_slot; - new_connection->socket = client; - new_connection->obj_id = new_object_slot; - - if (DEBUG & PLAYER_DEBUG) - fprintf(stdout, "Created connection with id '%d' and object '%d'\n", new_connection->id, new_object->id); - - SDL_CreateThread(handle_player, "client", new_connection); - } - - return 0; -} diff --git a/04-collision/server/src/structures.h b/04-collision/server/src/structures.h deleted file mode 100644 index d216630..0000000 --- a/04-collision/server/src/structures.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef STRUCTURES_H -#define STRUCTURES_H - -#include "structs.h" - -int map_find_empty_slot(void **map, int slots); -int map_allocate_value(void ***map, int *total_slots, int *used_slots, int bytes); - -#endif diff --git a/04-collision/.imgs/showcase.png b/04-map/.imgs/showcase.png similarity index 100% rename from 04-collision/.imgs/showcase.png rename to 04-map/.imgs/showcase.png diff --git a/04-map/README.md b/04-map/README.md new file mode 100644 index 0000000..fae3826 --- /dev/null +++ b/04-map/README.md @@ -0,0 +1,7 @@ + + + + +# Map + +My first attempt to recreate map generation in SDL. Both the server and the client run off of the SDL2 library. (alongside some extensions) diff --git a/04-collision/client/Makefile b/04-map/client/Makefile similarity index 100% rename from 04-collision/client/Makefile rename to 04-map/client/Makefile diff --git a/04-map/client/README.md b/04-map/client/README.md new file mode 100644 index 0000000..c78419b --- /dev/null +++ b/04-map/client/README.md @@ -0,0 +1,7 @@ + + + + +# Map - Client + +Client-side code for 04-map diff --git a/04-map/client/assets/floor/cobble.png b/04-map/client/assets/floor/cobble.png new file mode 100644 index 0000000..3fc1dbc Binary files /dev/null and b/04-map/client/assets/floor/cobble.png differ diff --git a/04-map/client/assets/floor/grass.png b/04-map/client/assets/floor/grass.png new file mode 100644 index 0000000..8db7bc6 Binary files /dev/null and b/04-map/client/assets/floor/grass.png differ diff --git a/04-map/client/assets/floor/lava.png b/04-map/client/assets/floor/lava.png new file mode 100644 index 0000000..38b8b28 Binary files /dev/null and b/04-map/client/assets/floor/lava.png differ diff --git a/04-map/client/assets/player/idle.png b/04-map/client/assets/player/idle.png new file mode 100644 index 0000000..4cf0c43 Binary files /dev/null and b/04-map/client/assets/player/idle.png differ diff --git a/04-map/client/assets/player/jump.png b/04-map/client/assets/player/jump.png new file mode 100644 index 0000000..1d12dec Binary files /dev/null and b/04-map/client/assets/player/jump.png differ diff --git a/04-map/client/assets/player/land.png b/04-map/client/assets/player/land.png new file mode 100644 index 0000000..2c24d6f Binary files /dev/null and b/04-map/client/assets/player/land.png differ diff --git a/04-map/client/assets/player/run.png b/04-map/client/assets/player/run.png new file mode 100644 index 0000000..615b222 Binary files /dev/null and b/04-map/client/assets/player/run.png differ diff --git a/04-collision/client/src/defs.h b/04-map/client/src/defs.h similarity index 73% rename from 04-collision/client/src/defs.h rename to 04-map/client/src/defs.h index df4f058..4b92daf 100644 --- a/04-collision/client/src/defs.h +++ b/04-map/client/src/defs.h @@ -13,14 +13,12 @@ #define MEMERR -2 // SDL2 -#define SCREEN_WIDTH 1000 -#define SCREEN_HEIGHT 480 #define WINDOW_FLAGS SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL #define RENDERER_FLAGS SDL_RENDERER_ACCELERATED // MCS: Message Communication Standard #define SERVER_MESSAGE_LEN 10 -#define CLIENT_MESSAGE_LEN 7 +#define CLIENT_MESSAGE_LEN 10 // MFS: Message Format Standard #define PLAYER_CONNECT_FORMAT 0 @@ -30,8 +28,12 @@ // MSCA: Message Communication Standard Actions #define LEFT_MOVEMENT 0b10000000 #define RIGHT_MOVEMENT 0b01000000 -#define UP_MOVEMENT 0b00100000 -#define DOWN_MOVEMENT 0b00010000 -#define NO_MOVEMENT 0b00000000 +#define JUMP_MOVEMENT 0b00100000 +#define CROUCH_MOVEMENT 0b00010000 + +// BS: Block Standard +#define GRASS_BLOCK 0b10000000 +#define COBBLE_BLOCK 0b01000000 +#define LAVA_BLOCK 0b00100000 #endif diff --git a/04-map/client/src/format.c b/04-map/client/src/format.c new file mode 100644 index 0000000..bf250e7 --- /dev/null +++ b/04-map/client/src/format.c @@ -0,0 +1,40 @@ +#include +#include "defs.h" +#include "structs.h" +#include "format.h" + +extern SDL_Texture *grass_texture; +extern SDL_Texture *cobble_texture; +extern SDL_Texture *lava_texture; +extern struct object *create_object(SDL_Texture *texture, int scale, int resolution); + +int handle_block_creation(int id, int type, struct object ***map, int *slots) { + (*slots)++; + *map = realloc(*map, sizeof(struct object *)*(*slots)); + if (*map == NULL) + return MEMERR; + + SDL_Texture *texture; + switch (type) { + case 0: + texture = grass_texture; + break; + case 1: + texture = cobble_texture; + break; + case 2: + texture = lava_texture; + break; + default: + texture = grass_texture; + break; + } + + struct object *new_block = create_object(texture, 1, 32); + if (new_block == NULL) + return MEMERR; + + (*map)[id] = new_block; + + return STDOK; +} diff --git a/04-map/client/src/format.h b/04-map/client/src/format.h new file mode 100644 index 0000000..3b9203b --- /dev/null +++ b/04-map/client/src/format.h @@ -0,0 +1,10 @@ +#ifndef FORMAT_H +#define FORMAT_H + +#include + +int handle_block_creation(int id, int type, struct object ***map, int *slots); +// int handle_player_connect(int *message, struct object ***map, int *slots); +// int handle_object_properties(int *message, struct object ***map, int *slots); + +#endif diff --git a/04-map/client/src/main.c b/04-map/client/src/main.c new file mode 100644 index 0000000..0aeeedd --- /dev/null +++ b/04-map/client/src/main.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include "structs.h" +#include "format.h" +#include "defs.h" + +#define DEBUG 1 +#define MAP_WIDTH 100 +#define MAP_HEIGHT 100 + +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; +} diff --git a/04-collision/client/src/object.c b/04-map/client/src/object.c similarity index 77% rename from 04-collision/client/src/object.c rename to 04-map/client/src/object.c index 6be16b5..7019603 100644 --- a/04-collision/client/src/object.c +++ b/04-map/client/src/object.c @@ -16,7 +16,7 @@ struct object *create_object(SDL_Texture *texture, int scale, int resolution) { return object; } -void draw_object(struct game *game, struct object *object) { +void frame_draw_object(struct game *game, struct object *object) { int texture_width; SDL_Rect src; SDL_Rect dest; @@ -45,6 +45,24 @@ void draw_object(struct game *game, struct object *object) { } } +void draw_object(struct game *game, struct object *object) { + SDL_Rect src; + SDL_Rect dest; + + src.x = 0; + src.y = 0; + src.w = object->resolution; + src.h = object->resolution; + + dest.x = object->x; + dest.y = object->y; + dest.w = object->resolution * object->scale; + dest.h = object->resolution * object->scale; + + SDL_RenderCopyEx(game->renderer, object->texture, &src, &dest, 0, NULL, SDL_FLIP_NONE); +} + + void switch_animation(struct object *object, SDL_Texture *animation) { if (object->texture == animation) return; diff --git a/04-collision/client/src/structs.h b/04-map/client/src/structs.h similarity index 92% rename from 04-collision/client/src/structs.h rename to 04-map/client/src/structs.h index fa37e25..64ca29e 100644 --- a/04-collision/client/src/structs.h +++ b/04-map/client/src/structs.h @@ -9,8 +9,7 @@ struct game { int left; int right; - int up; - int down; + int jump; }; struct animation { @@ -43,6 +42,7 @@ struct object { struct object *create_object(SDL_Texture *texture, int scale, int resolution); void draw_object(struct game *game, struct object *object); +void frame_draw_object(struct game *game, struct object *object); void switch_animation(struct object *object, SDL_Texture *animation); #endif diff --git a/04-collision/server/Makefile b/04-map/server/Makefile similarity index 100% rename from 04-collision/server/Makefile rename to 04-map/server/Makefile diff --git a/04-map/server/README.md b/04-map/server/README.md new file mode 100644 index 0000000..51f75f5 --- /dev/null +++ b/04-map/server/README.md @@ -0,0 +1,3 @@ +# Map - Server + +Server-side code for 04-map diff --git a/04-collision/server/src/defs.h b/04-map/server/src/defs.h similarity index 77% rename from 04-collision/server/src/defs.h rename to 04-map/server/src/defs.h index 3294e62..fedd149 100644 --- a/04-collision/server/src/defs.h +++ b/04-map/server/src/defs.h @@ -21,11 +21,16 @@ // MCSA: Message Communication Standard Actions #define LEFT_MOVEMENT 0b10000000 #define RIGHT_MOVEMENT 0b01000000 -#define UP_MOVEMENT 0b00100000 -#define DOWN_MOVEMENT 0b00010000 +#define JUMP_MOVEMENT 0b00100000 +#define CROUCH_MOVEMENT 0b00010000 // OC: Object Constants #define GRAVITY 2 #define MOVEMENT_SPEED 10 +// BS: Block Standard +#define GRASS_BLOCK 1 +#define COBBLE_BLOCK 2 +#define LAVA_BLOCK 3 + #endif diff --git a/04-collision/server/src/structures.c b/04-map/server/src/hashmap.c similarity index 81% rename from 04-collision/server/src/structures.c rename to 04-map/server/src/hashmap.c index 60e0cf7..a458183 100644 --- a/04-collision/server/src/structures.c +++ b/04-map/server/src/hashmap.c @@ -1,9 +1,9 @@ #include #include -#include "structures.h" +#include "hashmap.h" #include "defs.h" -int map_find_empty_slot(void **map, int slots) { +int find_empty_slot(void **map, int slots) { int slot = 0; if (slots <= 0) @@ -25,12 +25,12 @@ int map_find_empty_slot(void **map, int slots) { // If there's Nx fewer used slots than total slots in the map, find the first possible one. // Else reallocate the map and use the end slot // Then allocate an object of size BYTES and add it into the map. -int map_allocate_value(void ***map, int *total_slots, int *used_slots, int bytes) { +int allocate_value(void ***map, int *total_slots, int *used_slots, int bytes) { int half_slots = (*total_slots) / 2; int empty_slot = 0; if (*used_slots < half_slots) { - empty_slot = map_find_empty_slot(*map, *used_slots); + empty_slot = find_empty_slot(*map, *used_slots); goto jump; } @@ -51,5 +51,3 @@ jump: return empty_slot; } - - diff --git a/04-map/server/src/hashmap.h b/04-map/server/src/hashmap.h new file mode 100644 index 0000000..5beed26 --- /dev/null +++ b/04-map/server/src/hashmap.h @@ -0,0 +1,9 @@ +#ifndef HASHMAP_H +#define HASHMAP_H + +#include "structs.h" + +int find_empty_slot(void **map, int slots); +int allocate_value(void ***map, int *total_slots, int *used_slots, int bytes); + +#endif diff --git a/04-map/server/src/main.c b/04-map/server/src/main.c new file mode 100644 index 0000000..c6af2f2 --- /dev/null +++ b/04-map/server/src/main.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include "defs.h" +#include "structs.h" +#include "hashmap.h" + +#define DEBUG 0x0010 +#define PORT 9080 +#define MAP_WIDTH 100 +#define MAP_HEIGHT 100 + +struct connection **connections_map; +int connections_map_size = 0; +int connections_count = 0; + +int handle_connection(void *data) { + struct connection *connection_data = (struct connection *) data; + + struct map *new_map = generate_map(MAP_WIDTH, MAP_HEIGHT); + if (new_map == NULL) { + fprintf(stderr, "Erorr: failed generating map\n"); + goto end; + } + + SDLNet_TCP_Send(connection_data->socket, new_map->blocks, new_map->width*new_map->height*sizeof(int)); +end: + + SDLNet_TCP_Close(connection_data->socket); + connections_map[connection_data->id] = NULL; + connections_count--; + free(data); + + return 0; +} + +void catch_alarm(int sig) { + fprintf(stdout, "Notice: force stopping server...\n"); + exit(EXIT_SUCCESS); +} + +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[slot] == NULL) + break; + + slot++; + } + + return slot; +} + +int main(int argc, char *argv[]) { + signal(SIGINT, catch_alarm); + srand(time(NULL)); + + 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; + } + + IPaddress ip; + if (SDLNet_ResolveHost(&ip, NULL, PORT) == -1) { + fprintf(stderr, "Error: failed resolving host \n%s\n", SDL_GetError()); + return -1; + } + + TCPsocket server = SDLNet_TCP_Open(&ip); + if (!server) { + fprintf(stderr, "Error: failed opening socket at %d\n%s\n", PORT, SDL_GetError()); + return -1; + } + + for (;;) { + TCPsocket client = SDLNet_TCP_Accept(server); + if (!client) { + SDL_Delay(100); + continue; + } + + fprintf(stdout, "Notice: accepted a connection from client!\n"); + + int new_connection_slot = allocate_value((void ***) &connections_map, &connections_map_size, &connections_count, sizeof(struct connection)); + if (new_connection_slot == MEMERR) { + fprintf(stderr, "MEMERR: failed allocating memory for new connection\n"); + return STDERR; + } + + struct connection *new_connection = connections_map[new_connection_slot]; + + new_connection->id = new_connection_slot; + new_connection->socket = client; + + if (DEBUG & PLAYER_DEBUG) + fprintf(stdout, "Created connection with id '%d'\n", new_connection->id); + + SDL_CreateThread(handle_connection, "client", new_connection); + } + + return 0; +} diff --git a/04-map/server/src/map.c b/04-map/server/src/map.c new file mode 100644 index 0000000..b5911e7 --- /dev/null +++ b/04-map/server/src/map.c @@ -0,0 +1,29 @@ +#include +#include "structs.h" + +struct map *generate_map(int width, int height) { + struct map *new_map = (struct map *) calloc(1, sizeof(struct map)); + if (new_map == NULL) + return NULL; + + int *map_blocks = (int *) calloc(width*height, sizeof(int)); + if (map_blocks == NULL) + return NULL; + + new_map->width = width; + new_map->height = height; + new_map->blocks = map_blocks; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + double scale = ((double) rand() / RAND_MAX); + int block = scale * 3; + int index = (y*width)+x; + map_blocks[index] = block; + } + } + + fprintf(stdout, "Value of first block -> %d\n", map_blocks[0]); + + return new_map; +} diff --git a/04-collision/server/src/structs.h b/04-map/server/src/structs.h similarity index 51% rename from 04-collision/server/src/structs.h rename to 04-map/server/src/structs.h index aeb32d0..0db270b 100644 --- a/04-collision/server/src/structs.h +++ b/04-map/server/src/structs.h @@ -5,19 +5,15 @@ struct connection { int id; - int obj_id; TCPsocket socket; }; -struct object { - int id; - int x; - int y; - - int colliding; - int force; - - uint8_t state; +struct map { + int width; + int height; + int *blocks; }; +struct map *generate_map(int width, int height); + #endif