#include #include #include #include #include #include "game.h" #include "client.h" #include "protocol.h" #define WIDTH 640 #define HEIGHT 480 static const float ship[] = { +1.0, +0.0, -1.0, -1.0, +0.0, +0.0, -1.0, +1.0, +1.0, +0.0, }; static const float star[] = { +1.0, +0.0, +0.0, -1.0, -1.0, +0.0, +0.0, +1.0, +1.0, +0.0, }; static char * host = "localhost"; static char * nick = "Anonymous"; static uint16_t port = PROTOCOL_PORT; static SDL_Window * window; static SDL_Renderer * renderer; static void argverr() { SDL_Log("Invalid argument\n"); exit(1); } static void useargs(char ** argv) { int i = 1; while(argv[i]) { if(strcmp(argv[i], "-h") == 0) { if(argv[++i]) host = argv[i++]; else argverr(); } else if(strcmp(argv[i], "-p") == 0) { if(argv[++i]) port = atoi(argv[i++]); else argverr(); } else if(strcmp(argv[i], "-l") == 0) { if(argv[++i]) nick = argv[i++]; else argverr(); } else { argverr(); } } } static void sysinit() { if(SDL_Init(SDL_INIT_EVERYTHING) != 0) { SDL_Log("Unable to initialize SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); if(SDLNet_Init() != 0) { SDL_Log("Unable to initialize SDLNet: %s\n", SDLNet_GetError()); exit(1); } atexit(SDLNet_Quit); } static void openwindow() { SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer); SDL_RenderPresent(renderer); } static void closewindow() { SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); } static void paintmodel(const float * model, int modelsz, float mx, float my, float r, float size, int cx, int cy) { int scale = (WIDTH + HEIGHT) / 2 * size / 2; int count = modelsz / sizeof(model[0]) / 2; int x = mx * WIDTH / 2; int y = my * HEIGHT / 2; SDL_Point pix[count]; for(int j = 0; j < count * 2; j += 2) { float c = cos(r * 2 * M_PI); float s = sin(r * 2 * M_PI); float rx = model[j + 0] * scale; float ry = model[j + 1] * scale; pix[j / 2].x = cx + x + (c * rx - s * ry); pix[j / 2].y = cy + y + (s * rx + c * ry); } SDL_RenderDrawLines(renderer, pix, count); } static void paintwindow() { SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_RenderClear(renderer); int cx = WIDTH / 2; int cy = HEIGHT / 2; SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0xFF, 0x00); static float start_r; for(int i = 0; i < STAR_SIZE * 150; i++) paintmodel(star, sizeof(star), 0, 0, start_r + i * M_PI, STAR_SIZE, cx, cy); start_r += 0.0001; for(int i = 0; i < MAX_PLAYERS; i++) { if(i == cl_playerid) SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0x00); else SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00); if(g_player[i].live) paintmodel(ship, sizeof(ship), g_player[i].x, g_player[i].y, g_player[i].r, PLAYER_SIZE, cx, cy); } for(int i = 0; i < MAX_BULLETS; i++) { if(g_bullet[i].owner == cl_playerid) SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0x00); else SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00); int x = g_bullet[i].x * WIDTH / 2; int y = g_bullet[i].y * HEIGHT / 2; if(g_bullet[i].live) SDL_RenderDrawPoint(renderer, cx + x, cy + y); } SDL_RenderPresent(renderer); } static void keyboardhandle() { SDL_PumpEvents(); const Uint8 * key = SDL_GetKeyboardState(NULL); cl_move((DoesBits) { .up = key[SDL_SCANCODE_UP], .down = key[SDL_SCANCODE_DOWN], .left = key[SDL_SCANCODE_LEFT], .right = key[SDL_SCANCODE_RIGHT], .fire = key[SDL_SCANCODE_LCTRL], }); } int main(int argc, char ** argv) { sysinit(); useargs(argv); openwindow(); cl_connect(host, port); while(cl_playerid >= 0) { SDL_Event event; while(SDL_PollEvent(&event)) if(event.type == SDL_QUIT) goto cleanup; keyboardhandle(); cl_handle(); paintwindow(); SDL_Delay(1); } cleanup: closewindow(); cl_disconnect(false); return 0; }