From 47987ca4396e1f2143d1d9347f57b4d4532d63bb Mon Sep 17 00:00:00 2001 From: roseen Date: Sat, 31 Jan 2026 18:42:43 -0600 Subject: [PATCH] working on making game lobbies and joining them --- Makefile | 24 +++-- README.md | 12 +-- client | 1 + net/client.c => client.c | 0 game | 1 + host.c | 208 ++++++++++++++++++++++++++------------- include/game.h | 1 + include/host.h | 2 + include/net.h | 46 ++++++++- input.c | 23 +++-- net.h | 48 --------- server | 1 + server.c | 3 - server_test.c | 137 -------------------------- 14 files changed, 227 insertions(+), 280 deletions(-) create mode 120000 client rename net/client.c => client.c (100%) create mode 120000 game delete mode 100644 net.h create mode 120000 server delete mode 100644 server_test.c diff --git a/Makefile b/Makefile index 5b16d3e..d2c8831 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ CC =gcc CFLAGS =-g CPPFLAGS =-c -g -Wall -pedantic -Wextra LDFLAGS =-lSDL2 -lm -lSDL2main -lSDL2_image -LDFLAGS +=-L/usr/local/lib -lSDL2_ttf -INCFLAGS = -I. -Iinclude +LDFLAGS +=-L/usr/local/lib -lSDL2_ttf -lSDL2_net +INCFLAGS = -I/usr/local/include/SDL2 -Iinclude INC =include/ @@ -19,7 +19,7 @@ ifeq ($(debug),on) CPPFLAGS += -Ddebug endif -BINARIES = game client_test server_test +BINARIES = game client server all : $(BINARIES) @@ -63,6 +63,17 @@ $(OBJ)game.o : game.c $(INC)game.h | $(OBJ) $(OBJ)overworld.o : overworld.c $(INC)overworld.h | $(OBJ) $(CC) $(CPPFLAGS) -o $@ $< $(INCFLAGS) +$(OBJ)net.o : net.c $(INC)net.h | $(OBJ) + $(CC) $(CPPFLAGS) -o $@ $< $(INCFLAGS) + +$(OBJ)client.o : client.c $(INC)net.h | $(OBJ) + $(CC) $(CPPFLAGS) -o $@ $< $(INCFLAGS) + +$(OBJ)server.o : server.c $(INC)net.h | $(OBJ) + $(CC) $(CPPFLAGS) -o $@ $< $(INCFLAGS) + + + ## --- LIBRARY FILES --- @@ -73,14 +84,15 @@ $(OBJ)overworld.o : overworld.c $(INC)overworld.h | $(OBJ) #$(BIN) : $(OBJ) | $(BIN) # $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -$(BIN)client_test : $(OBJ)client_test.o | $(BIN) +$(BIN)client : $(OBJ)client.o | $(BIN) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -$(BIN)server_test: $(OBJ)server_test.o | $(BIN) +$(BIN)server: $(OBJ)server.o | $(BIN) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(BIN)game : $(OBJ)main.o $(OBJ)input.o $(OBJ)battle.o $(OBJ)game.o\ - $(OBJ)options.o $(OBJ)host.o $(OBJ)join.o $(OBJ)overworld.o | $(BIN) + $(OBJ)options.o $(OBJ)host.o $(OBJ)join.o $(OBJ)overworld.o $(OBJ)net.o\ + | $(BIN) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BINARIES) : % : $(BIN)% diff --git a/README.md b/README.md index a789c24..6338642 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,18 @@ DEPENDANCIES SDL CORE: use SDL 2.24.x -https://github.com/libsdl-org/SDL.git +git clone https://github.com/libsdl-org/SDL.git cd SDL git checkout release-2.24.x mkdir build cd build -cmake .. -sudo make install +cmake .. -DCMAKE_POLICY_VERSION_MINIMUM=3.5 +sudo make install -j SDL IMAGE: use SDL_Image 2.8.x -https://github.com/libsdl-org/SDL_image.git +git clone https://github.com/libsdl-org/SDL_image.git cd SDL_image git checkout release-2.8.x mkdir build @@ -30,7 +30,7 @@ sudo make install SDL_Net: use SDL_Net 2.2.x -https://github.com/libsdl-org/SDL_net.git +git clone https://github.com/libsdl-org/SDL_net.git cd SDL_net git checkout release-2.2.x mkdir build @@ -41,7 +41,7 @@ sudo make install SDL_ttf use SDL_ttf 2.24.x -https://github.com/libsdl-org/SDL_ttf.git +git clone https://github.com/libsdl-org/SDL_ttf.git cd SDL_ttf git checkout release-2.24.x mkdir build diff --git a/client b/client new file mode 120000 index 0000000..f457900 --- /dev/null +++ b/client @@ -0,0 +1 @@ +build/bin/client \ No newline at end of file diff --git a/net/client.c b/client.c similarity index 100% rename from net/client.c rename to client.c diff --git a/game b/game new file mode 120000 index 0000000..5aa2eea --- /dev/null +++ b/game @@ -0,0 +1 @@ +build/bin/game \ No newline at end of file diff --git a/host.c b/host.c index 81e0104..60aa5b9 100644 --- a/host.c +++ b/host.c @@ -17,27 +17,148 @@ int over_object; char player_names[MAX_PLAYERS][MAX_NAMESZ]; -char last_sent_name[MAX_NAMESZ]; +char temp_name[MAX_NAMESZ]; +char lobby_name[MAX_NAMESZ]; +char lobby_name_perm[MAX_NAMESZ]; int num_players = 1; +int lobby_has_name = 0; + + + +SDL_Rect set_name_rect, name_rect, player_name_rect; +SDL_Rect player_rects[MAX_PLAYERS]; +SDL_Rect player_name_rects[MAX_PLAYERS]; +SDL_Rect start_rect; + +TTF_Font* font; +SDL_Color white = {255, 255, 255, 0}; +SDL_Surface *set_name_surf; +SDL_Surface *start_surf; +SDL_Surface *lobby_name_surf; + +SDL_Texture *set_name_tex; +SDL_Texture *lobby_name_tex; +SDL_Texture *start_tex; + +SDL_Surface *player_name_surfs[MAX_PLAYERS]; +SDL_Surface *player_tempname_surf; +SDL_Texture *player_name_texs[MAX_PLAYERS]; +SDL_Texture *player_tempname_tex; + + char *get_this_name(int i) { - if(i >= 0 && i < MAX_PLAYERS){ return player_names[i]; } + + if(!lobby_has_name) { + if(i == -1){return lobby_name; } + if(i == 0) { return lobby_name_perm; } + } + else{ + if(i == -1) { return temp_name; } + if(i >= 0 && i < MAX_PLAYERS){ + return player_names[i]; + } + } return NULL; } +void render_lobby() +{ + int i; + + player_tempname_surf= TTF_RenderText_Solid(font, temp_name, white); + player_tempname_tex = SDL_CreateTextureFromSurface(renderer, player_tempname_surf); + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + //set name button + SDL_SetRenderDrawColor(renderer, 64, 64, 64,255); + SDL_RenderFillRect(renderer, &set_name_rect); + SDL_RenderCopy(renderer, set_name_tex, NULL, &(set_name_rect)); + + //player fields + for(i = 0; i < MAX_PLAYERS; i++) + { + player_name_rects[i].w = (player_rects[0].w / MAX_NAMESZ) * strlen(player_names[i]); + player_name_surfs[i] = TTF_RenderText_Solid(font, player_names[i], white); + player_name_texs[i] = SDL_CreateTextureFromSurface(renderer, player_name_surfs[i]); + SDL_RenderFillRect(renderer, &(player_rects[i])); + SDL_RenderCopy(renderer, player_name_texs[i], NULL, &(player_name_rects[i])); + } + //name field + player_name_rect.w = (name_rect.w / MAX_NAMESZ) * strlen(temp_name); + SDL_RenderFillRect(renderer, &name_rect); + SDL_RenderCopy(renderer, player_tempname_tex, NULL, &player_name_rect); + + //start game button + SDL_RenderFillRect(renderer, &start_rect); + SDL_RenderCopy(renderer, start_tex, NULL, &(start_rect)); + + + SDL_RenderPresent(renderer); + + player_tempname_surf= TTF_RenderText_Solid(font, temp_name, white); + player_tempname_tex = SDL_CreateTextureFromSurface(renderer, player_tempname_surf); + + SDL_FreeSurface(player_tempname_surf); + SDL_DestroyTexture(player_tempname_tex); + for(i = 0; i < MAX_PLAYERS; i++) + { + SDL_FreeSurface(player_name_surfs[i]); + SDL_DestroyTexture(player_name_texs[i]); + } +} + +void render_lobby_name() +{ + + lobby_name_surf = TTF_RenderText_Solid(font, lobby_name, white); + lobby_name_tex = SDL_CreateTextureFromSurface(renderer, lobby_name_surf); + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + //set lobby name button + SDL_SetRenderDrawColor(renderer, 64, 64, 64,255); + SDL_RenderFillRect(renderer, &set_name_rect); + SDL_RenderCopy(renderer, set_name_tex, NULL, &(set_name_rect)); + + //name field + player_name_rect.w = (name_rect.w / MAX_NAMESZ) * strlen(lobby_name); + SDL_RenderFillRect(renderer, &name_rect); + SDL_RenderCopy(renderer, lobby_name_tex, NULL, &player_name_rect); + + //start game button + SDL_RenderFillRect(renderer, &start_rect); + SDL_RenderCopy(renderer, start_tex, NULL, &(start_rect)); + + SDL_RenderPresent(renderer); + +} + +void render_main() +{ + SDL_GetMouseState(&(mouse_pos.x), &(mouse_pos.y)); + + if(SDL_PointInRect(&mouse_pos, &start_rect)){ + over_object = START_GAME_BUTTON; + } + else if(SDL_PointInRect(&mouse_pos, &set_name_rect)){ + over_object = SET_NAME_BUTTON; + } + + handle_event(&event); + + if(lobby_has_name){ render_lobby(); } + else{ render_lobby_name(); } +} void host_game(){ int i; PRINT_M(HOST state) - SDL_Point mouse_pos; - - SDL_Rect set_name_rect, name_rect, player_name_rect; - SDL_Rect player_rects[MAX_PLAYERS]; - SDL_Rect player_name_rects[MAX_PLAYERS]; - SDL_Rect start_rect; - over_object = NO_OBJECT; strcpy(player_names[0], "player_1"); @@ -45,14 +166,13 @@ void host_game(){ strcpy(player_names[2], "no_player_3"); strcpy(player_names[3], "no_player_4"); - TTF_Font* font = TTF_OpenFont("assets/font.ttf", 24); - SDL_Color white = {255, 255, 255, 0}; - SDL_Surface *set_name_surf = TTF_RenderText_Solid(font, "set name", white); - SDL_Surface *start_surf = TTF_RenderText_Solid(font, "start game", white); + font = TTF_OpenFont("assets/font.ttf", 24); + set_name_surf = TTF_RenderText_Solid(font, "set name", white); + start_surf = TTF_RenderText_Solid(font, "start game", white); + lobby_name_surf = TTF_RenderText_Solid(font, lobby_name, white); - SDL_Texture *set_name_tex = SDL_CreateTextureFromSurface(renderer, set_name_surf); - SDL_Texture *start_tex = SDL_CreateTextureFromSurface(renderer, start_surf); - + set_name_tex = SDL_CreateTextureFromSurface(renderer, set_name_surf); + start_tex = SDL_CreateTextureFromSurface(renderer, start_surf); set_name_rect.w = DEF_WINDOW_WIDTH >> 3; @@ -99,61 +219,11 @@ void host_game(){ SDL_StartTextInput(); SDL_SetTextInputRect(&name_rect); - SDL_Surface *player_name_surfs[MAX_PLAYERS]; - SDL_Texture *player_name_texs[MAX_PLAYERS]; - - + while(running) { - - SDL_GetMouseState(&(mouse_pos.x), &(mouse_pos.y)); - - if(SDL_PointInRect(&mouse_pos, &start_rect)) - { - over_object = START_GAME_BUTTON; - } - else if(SDL_PointInRect(&mouse_pos, &set_name_rect)) - { - over_object = SET_NAME_BUTTON; - } - - - handle_event(&event); - - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - - //set name button - SDL_SetRenderDrawColor(renderer, 64, 64, 64,255); - SDL_RenderFillRect(renderer, &set_name_rect); - SDL_RenderCopy(renderer, set_name_tex, NULL, &(set_name_rect)); - - //player fields - for(i = 0; i < MAX_PLAYERS; i++) - { - player_name_rects[i].w = (player_rects[0].w / MAX_NAMESZ) * strlen(player_names[i]); - player_name_surfs[i] = TTF_RenderText_Solid(font, player_names[i], white); - player_name_texs[i] = SDL_CreateTextureFromSurface(renderer, player_name_surfs[i]); - SDL_RenderFillRect(renderer, &(player_rects[i])); - SDL_RenderCopy(renderer, player_name_texs[i], NULL, &(player_name_rects[i])); - } - //name field - player_name_rect.w = (name_rect.w / MAX_NAMESZ) * strlen(player_names[0]); - SDL_RenderFillRect(renderer, &name_rect); - SDL_RenderCopy(renderer, player_name_texs[0], NULL, &player_name_rect); - - //start game button - SDL_RenderFillRect(renderer, &start_rect); - SDL_RenderCopy(renderer, start_tex, NULL, &(start_rect)); - - - SDL_RenderPresent(renderer); - for(i = 0; i < MAX_PLAYERS; i++) - { - SDL_FreeSurface(player_name_surfs[i]); - SDL_DestroyTexture(player_name_texs[i]); - } - } + render_main(); + } return; } diff --git a/include/game.h b/include/game.h index 4e2f30d..33b9ec4 100644 --- a/include/game.h +++ b/include/game.h @@ -5,6 +5,7 @@ #include +extern SDL_Point mouse_pos; #define TITLE 0 #define START 1 diff --git a/include/host.h b/include/host.h index 351e91f..194efc0 100644 --- a/include/host.h +++ b/include/host.h @@ -7,6 +7,8 @@ #define START_GAME_BUTTON 2 extern int over_object; +extern int lobby_has_name; + char *get_this_name(int i); diff --git a/include/net.h b/include/net.h index 3d02337..88497bc 100644 --- a/include/net.h +++ b/include/net.h @@ -1,12 +1,48 @@ //Troy Rosin - -#ifndef __netcode_h__ -#define __netcode_h__ +#ifndef __my_net_h__ +#define __my_net_h__ #define PORT 36911 -void init_network(); +#define SERVER "localhost" + +#define PACKSZ 1024 + +enum pack_type{ + G_STATE, S_STATE, HOSTS_REQ, NEW_HOST, JOIN_REQ, U_NAME +}; + +typedef struct packet{ + enum pack_type type; + char payload[PACKSZ - sizeof(enum pack_type)]; +} packet; + + +int read_to_buff(Uint32 *buff, Uint32 *src, Uint32 sz) +{ + if(sz%32){ + puts("error size must be div by 32"); + return 0; + } + for(Uint32 i = 0; i < (sz >> 2); i += 1) + { + *(buff + i) = SDLNet_Read32(src + i); + } + return 1; +} + +int write_to_buff(Uint32 *buff, Uint32 *src, Uint32 sz) +{ + if(sz%32){ + puts("error size must be div by 32"); + return 0; + } + for(Uint32 i = 0; i < (sz >> 2); i += 1) + { + SDLNet_Write32(*(src + i), (buff + i)); + } + return 1; +} #endif - diff --git a/input.c b/input.c index 6533eb9..b07e132 100644 --- a/input.c +++ b/input.c @@ -153,11 +153,10 @@ void handle_input_host(SDL_Event *e) { int oldlen, inputlen; char tempname[MAX_NAMESZ], *nameptr; - nameptr = get_this_name(0); + nameptr = get_this_name(-1); strcpy(tempname, nameptr); oldlen = strlen(tempname); - inputlen = strlen(e->text.text); - + switch(e->type) { case SDL_KEYUP: @@ -177,14 +176,26 @@ void handle_input_host(SDL_Event *e) } break; case SDL_TEXTINPUT: + inputlen = strlen(e->text.text); PRINT_M(got text input event) if(oldlen + inputlen > MAX_NAMESZ -1){ break; } strcat(tempname, e->text.text); strcpy(nameptr, tempname); break; - - default: - printf("got event type: %u\n", e->type); + case SDL_MOUSEBUTTONDOWN: + switch(over_object) + { + case NO_OBJECT: + break; + case SET_NAME_BUTTON: + strcpy(get_this_name(0), nameptr); + break; + case START_GAME_BUTTON: + if(strlen(get_this_name(0)) >= 1){ + lobby_has_name = 1; + } + break; + } } return; } diff --git a/net.h b/net.h deleted file mode 100644 index 88497bc..0000000 --- a/net.h +++ /dev/null @@ -1,48 +0,0 @@ -//Troy Rosin -#ifndef __my_net_h__ -#define __my_net_h__ - -#define PORT 36911 - -#define SERVER "localhost" - -#define PACKSZ 1024 - -enum pack_type{ - G_STATE, S_STATE, HOSTS_REQ, NEW_HOST, JOIN_REQ, U_NAME -}; - -typedef struct packet{ - enum pack_type type; - char payload[PACKSZ - sizeof(enum pack_type)]; -} packet; - - -int read_to_buff(Uint32 *buff, Uint32 *src, Uint32 sz) -{ - if(sz%32){ - puts("error size must be div by 32"); - return 0; - } - for(Uint32 i = 0; i < (sz >> 2); i += 1) - { - *(buff + i) = SDLNet_Read32(src + i); - } - return 1; -} - -int write_to_buff(Uint32 *buff, Uint32 *src, Uint32 sz) -{ - if(sz%32){ - puts("error size must be div by 32"); - return 0; - } - for(Uint32 i = 0; i < (sz >> 2); i += 1) - { - SDLNet_Write32(*(src + i), (buff + i)); - } - return 1; -} - - -#endif diff --git a/server b/server new file mode 120000 index 0000000..506e61f --- /dev/null +++ b/server @@ -0,0 +1 @@ +build/bin/server \ No newline at end of file diff --git a/server.c b/server.c index d9278ed..1b80504 100644 --- a/server.c +++ b/server.c @@ -89,7 +89,6 @@ void game_server() break; case U_NAME: PRINT_M("got to update name state"); - flag = 0; break; } } @@ -110,13 +109,11 @@ void game_server() } } } - return; } SDLNet_TCP_Close(sock); SDLNet_Quit(); SDL_Quit(); - } diff --git a/server_test.c b/server_test.c deleted file mode 100644 index 1048efb..0000000 --- a/server_test.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -** server.c -- a stream socket server demo -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PORT "3490" // the port users will be connecting to - -#define BACKLOG 10 // how many pending connections queue will hold - -void sigchld_handler(int s) -{ - (void)s; // quiet unused variable warning - - // waitpid() might overwrite errno, so we save and restore it: - int saved_errno = errno; - - while(waitpid(-1, NULL, WNOHANG) > 0); - - errno = saved_errno; -} - - -// get sockaddr, IPv4 or IPv6: -void *get_in_addr(struct sockaddr *sa) -{ - if (sa->sa_family == AF_INET) { - return &(((struct sockaddr_in*)sa)->sin_addr); - } - - return &(((struct sockaddr_in6*)sa)->sin6_addr); -} - -int main(void) -{ - // listen on sock_fd, new connection on new_fd - int sockfd, new_fd; - struct addrinfo hints, *servinfo, *p; - struct sockaddr_storage their_addr; // connector's address info - socklen_t sin_size; - struct sigaction sa; - int yes=1; - char s[INET6_ADDRSTRLEN]; - int rv; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; // use my IP - - if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); - return 1; - } - - // loop through all the results and bind to the first we can - for(p = servinfo; p != NULL; p = p->ai_next) { - if ((sockfd = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) { - perror("server: socket"); - continue; - } - - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, - sizeof(int)) == -1) { - perror("setsockopt"); - exit(1); - } - - if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { - close(sockfd); - perror("server: bind"); - continue; - } - - break; - } - - freeaddrinfo(servinfo); // all done with this structure - - if (p == NULL) { - fprintf(stderr, "server: failed to bind\n"); - exit(1); - } - - if (listen(sockfd, BACKLOG) == -1) { - perror("listen"); - exit(1); - } - - sa.sa_handler = sigchld_handler; // reap all dead processes - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - if (sigaction(SIGCHLD, &sa, NULL) == -1) { - perror("sigaction"); - exit(1); - } - - printf("server: waiting for connections...\n"); - - while(1) { // main accept() loop - sin_size = sizeof their_addr; - new_fd = accept(sockfd, (struct sockaddr *)&their_addr, - &sin_size); - if (new_fd == -1) { - perror("accept"); - continue; - } - - inet_ntop(their_addr.ss_family, - get_in_addr((struct sockaddr *)&their_addr), - s, sizeof s); - printf("server: got connection from %s\n", s); - - if (!fork()) { // this is the child process - close(sockfd); // child doesn't need the listener - if (send(new_fd, "Hello, world!", 13, 0) == -1) - perror("send"); - close(new_fd); - exit(0); - } - close(new_fd); // parent doesn't need this - } - - return 0; -}