-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
180 lines (179 loc) · 4.85 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once
#include "Square.h"
#include "updater.h"
#include "menu.h"
#include <chrono>
#include <iostream>
#undef main
int_least32_t main() {
std::ios_base::sync_with_stdio(false);
//Init part
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
WSADATA data{};
WSAStartup(MAKEWORD(2, 2), &data);
//Window & Renderer creation
SDL_DisplayMode dm{};
SDL_GetDesktopDisplayMode(0, &dm);
int_least32_t width{ static_cast<int_least32_t> (dm.w / 2) };
int_least32_t height{ static_cast<int_least32_t>(dm.h / 2) };
SDL_Window* win{ SDL_CreateWindow("Squares playground", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED) };
SDL_Renderer* ren{ SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED) };
//Event List
SDL_Event ev{};
//Main loop & events
bool loop{ true };
unsigned char gamestate{ 0 };
// Game mechanic part
updater upr{ win,ren,&gamestate,&ev };
title tt{};
host_b hb{};
join_b jb{};
tomenu_b tmb{};
hostinfo hif{};
field cfd{};
enter2join e2j{};
lchost_b lct{};
phost_b phs{};
authorize auth{};
auth.dflag = 0;
Square tsqr{};
TTF_Font* namefont{ TTF_OpenFont("times.ttf", 20) };
Sqrc squares{};
squares.reserve(max_player);
//Networking
sockaddr_in dest{};
SOCKET tsock{};
pollfd set{};
//Timer for movement and other variables
bool condition{ true };
std::chrono::steady_clock::time_point later {};
double deltat{};
uint_least64_t p1{};
while (loop) {
deltat = (SDL_GetPerformanceCounter() - p1 + 0.0) / SDL_GetPerformanceFrequency();
p1 = SDL_GetPerformanceCounter();
//performance control
switch (gamestate) {
case GAMEPLAY:
SDL_PollEvent(&ev);
break;
case PREJOIN:
case JOINMENU:
SDL_WaitEventTimeout(&ev, 50);
break;
default:
SDL_WaitEvent(&ev);
break;
}
if (SDL_GetWindowFlags(win) & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_HIDDEN)) {
SDL_WaitEvent(&ev);
}
//main event handler
switch (ev.type) {
case SDL_QUIT: {
lReq(dest, tsock, tsqr.index);
shutdown(tsock, SD_BOTH);
closesocket(tsock);
loop = false;
}
}
//gamestate
SDL_SetRenderDrawColor(ren, 255, 255, 255, 0);
SDL_RenderClear(ren);
switch (gamestate) {
case MAINMENU: {
upr.draw_titles(tt)->handle_host_b(hb)->handle_join_b(jb, auth, cfd);
break;
}
case JOINMENU: {
[&](){if (auth.dflag == 1) {
if (condition) {
later = std::chrono::steady_clock::now() + std::chrono::milliseconds(1000);
condition = false;
}
if (std::chrono::steady_clock::now() >= later) {
auth.dflag = 0;
condition = true;
return;
}
}}();
upr.draw_titles(tt)->handle_tomenu_b(tmb)->handle_field(cfd, dest, auth)
->draw_enter2join(e2j)->draw_authorize(auth);
break;
}
case GAMEPLAY: {
set.events = POLLRDNORM | POLLWRNORM;
if (WSAPoll(&set, 1, 0) == 1 && (set.revents == (POLLRDNORM | POLLWRNORM))) {
processMsg(tsock, squares, tsqr, dest);
}
set.events = POLLWRNORM;
if (WSAPoll(&set, 1, 0) == 1 && set.revents == POLLWRNORM && std::chrono::steady_clock::now() >= later) {
later = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(0.1 - deltat));
pUpdate(dest, tsock, tsqr);
}
//Handle this square
upr.handle_input(tsqr, 1/deltat)->handle_border_collision(tsqr)->draw_sqr(tsqr, namefont, tsqr.index);
//Other player square handle
for (auto& i : squares) {
upr.draw_sqr(*i.second, namefont, tsqr.index);
}
upr.handle_hostinfo(hif);
break;
}
case HOSTMENU: {
upr.handle_lchost_b(lct)->handle_tomenu_b(tmb)->handle_phost_b(phs)->draw_titles(tt);
break;
}
case PREHOST: {
int res{ prepareRoom(dest, tsock, tsqr) };
if (res != 0) {
std::cout << res;
closesocket(tsock);
gamestate = HOSTMENU;
break;
};
hif.storage = std::to_string(dest.sin_port * 3);
std::cout << "Real hosted port: " << ntohs(dest.sin_port);
set.fd = tsock;
set.events = POLLRDNORM | POLLWRNORM;
gamestate = GAMEPLAY;
break;
}
case PREJOIN: {
int res{ joinRoom(dest, tsock, tsqr) };
if (res != 0) {
closesocket(tsock);
auth.dflag = 1;
std::cout << res;
gamestate = JOINMENU;
break;
};
iReq(dest, tsock, tsqr);
if (processMsg(tsock, squares, tsqr, dest) == 0) {
set.fd = tsock;
hif.storage = std::to_string(dest.sin_port * 3);
std::cout << "Real joined port: " << ntohs(dest.sin_port) << '\n';
gamestate = GAMEPLAY;
}
else {
closesocket(tsock);
auth.dflag = 1;
gamestate = JOINMENU;
}
break;
}
default: {
std::cout << "Error: No such gamestate";
loop = false;
break;
}
}
SDL_RenderPresent(ren);
}
upr.closefont(tt.font)->closefont(tt.joinfont)->closefont(tt.hostfont)
->closefont(tmb.font)->closefont(hb.font)->closefont(jb.font)
->closefont(hif.font)->closefont(phs.font)->closefont(lct.font);
TTF_Quit();
SDL_Quit();
}