source: network-game/client/Client/main.cpp@ d2b411a

Last change on this file since d2b411a was 0cc431d, checked in by dportnoy <dmp1488@…>, 12 years ago

Added a state to the client and began using message types. Created a simple system for sending the username to the server before being logged in

  • Property mode set to 100644
File size: 8.0 KB
Line 
1#include "../../common/compiler.h"
2
3#if defined WINDOWS
4 #include <winsock2.h>
5 #include <WS2tcpip.h>
6#elif defined LINUX
7 #include <sys/types.h>
8 #include <unistd.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12 #include <cstring>
13#endif
14
15#include <sys/types.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string>
19#include <iostream>
20#include <vector>
21
22#include <allegro5/allegro.h>
23#include <allegro5/allegro_font.h>
24#include <allegro5/allegro_ttf.h>
25
26#include "../../common/message.h"
27
28#include "chat.h"
29
30#ifdef WINDOWS
31 #pragma comment(lib, "ws2_32.lib")
32#endif
33
34using namespace std;
35
36void initWinSock();
37void shutdownWinSock();
38void error(const char *);
39
40const float FPS = 60;
41const int SCREEN_W = 640;
42const int SCREEN_H = 480;
43const int BOUNCER_SIZE = 32;
44enum MYKEYS {
45 KEY_UP,
46 KEY_DOWN,
47 KEY_LEFT,
48 KEY_RIGHT
49};
50
51enum STATE {
52 STATE_START,
53 STATE_LOGIN
54};
55
56int main(int argc, char **argv)
57{
58 ALLEGRO_DISPLAY *display = NULL;
59 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
60 ALLEGRO_TIMER *timer = NULL;
61 ALLEGRO_BITMAP *bouncer = NULL;
62 float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
63 float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
64 bool key[4] = { false, false, false, false };
65 bool redraw = true;
66 bool doexit = false;
67
68 int state = STATE_START;
69
70 chat chatConsole;
71
72 if(!al_init()) {
73 fprintf(stderr, "failed to initialize allegro!\n");
74 return -1;
75 }
76
77 al_init_font_addon();
78 al_init_ttf_addon();
79
80 ALLEGRO_FONT *font = al_load_ttf_font("../pirulen.ttf", 12, 0);
81
82 if (!font) {
83 fprintf(stderr, "Could not load 'pirulen.ttf'.\n");
84 getchar();
85 return -1;
86 }
87
88 if(!al_install_keyboard()) {
89 fprintf(stderr, "failed to initialize the keyboard!\n");
90 return -1;
91 }
92
93 timer = al_create_timer(1.0 / FPS);
94 if(!timer) {
95 fprintf(stderr, "failed to create timer!\n");
96 return -1;
97 }
98
99 display = al_create_display(SCREEN_W, SCREEN_H);
100 if(!display) {
101 fprintf(stderr, "failed to create display!\n");
102 al_destroy_timer(timer);
103 return -1;
104 }
105
106 bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
107 if(!bouncer) {
108 fprintf(stderr, "failed to create bouncer bitmap!\n");
109 al_destroy_display(display);
110 al_destroy_timer(timer);
111 return -1;
112 }
113
114 event_queue = al_create_event_queue();
115 if(!event_queue) {
116 fprintf(stderr, "failed to create event_queue!\n");
117 al_destroy_bitmap(bouncer);
118 al_destroy_display(display);
119 al_destroy_timer(timer);
120 return -1;
121 }
122
123 al_set_target_bitmap(bouncer);
124
125 al_clear_to_color(al_map_rgb(255, 0, 255));
126
127 al_set_target_bitmap(al_get_backbuffer(display));
128
129 al_register_event_source(event_queue, al_get_display_event_source(display));
130
131 al_register_event_source(event_queue, al_get_timer_event_source(timer));
132
133 al_register_event_source(event_queue, al_get_keyboard_event_source());
134
135 al_clear_to_color(al_map_rgb(0,0,0));
136
137 al_flip_display();
138
139 int sock, n;
140 struct sockaddr_in server, from;
141 struct hostent *hp;
142 //char buffer[256];
143 NETWORK_MSG msgTo, msgFrom;
144
145 if (argc != 3) {
146 cout << "Usage: server port" << endl;
147 exit(1);
148 }
149
150 initWinSock();
151
152 sock = socket(AF_INET, SOCK_DGRAM, 0);
153 if (sock < 0)
154 error("socket");
155
156 server.sin_family = AF_INET;
157 hp = gethostbyname(argv[1]);
158 if (hp==0)
159 error("Unknown host");
160
161 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
162 server.sin_port = htons(atoi(argv[2]));
163
164 strcpy(msgTo.buffer, "Hello");
165 n=sendMessage(&msgTo, sock, &server);
166 if (n < 0)
167 error("sendMessage");
168
169 n = receiveMessage(&msgFrom, sock, &from);
170 if (n < 0)
171 error("receiveMessage");
172
173 chatConsole.addLine(msgFrom.buffer);
174
175 al_start_timer(timer);
176
177 while(!doexit)
178 {
179 ALLEGRO_EVENT ev;
180 al_wait_for_event(event_queue, &ev);
181
182 if(ev.type == ALLEGRO_EVENT_TIMER) {
183 if(key[KEY_UP] && bouncer_y >= 4.0) {
184 bouncer_y -= 4.0;
185 }
186
187 if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) {
188 bouncer_y += 4.0;
189 }
190
191 if(key[KEY_LEFT] && bouncer_x >= 4.0) {
192 bouncer_x -= 4.0;
193 }
194
195 if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) {
196 bouncer_x += 4.0;
197 }
198
199 redraw = true;
200 }
201 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
202 doexit = true;
203 }
204 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
205 bool eventConsumed = chatConsole.processEvent(ev);
206
207 if (eventConsumed) {
208 string input = chatConsole.getInput();
209 if (!input.empty()) {
210 cout << "input: " << input << endl;
211 strcpy(msgTo.buffer, input.c_str());
212
213 switch(state)
214 {
215 case STATE_START:
216 msgTo.type = MSG_TYPE_LOGIN;
217 break;
218 case STATE_LOGIN:
219 msgTo.type = MSG_TYPE_CHAT;
220 break;
221 default:
222 cout << "The state has an invalid value: " << state << endl;
223 break;
224 }
225
226 n=sendMessage(&msgTo, sock, &server);
227 if (n < 0)
228 error("sendMessage");
229
230 n = receiveMessage(&msgFrom, sock, &from);
231 if (n < 0)
232 error("receiveMessage");
233
234 switch(state)
235 {
236 case STATE_START:
237 state = STATE_LOGIN;
238 break;
239 case STATE_LOGIN:
240 chatConsole.addLine(string(msgFrom.buffer));
241 cout << "Added new line" << endl;
242 break;
243 default:
244 cout << "The state has an invalid value: " << state << endl;
245 break;
246 }
247 }
248 }else {
249 switch(ev.keyboard.keycode) {
250 case ALLEGRO_KEY_UP:
251 key[KEY_UP] = true;
252 break;
253
254 case ALLEGRO_KEY_DOWN:
255 key[KEY_DOWN] = true;
256 break;
257
258 case ALLEGRO_KEY_LEFT:
259 key[KEY_LEFT] = true;
260 break;
261
262 case ALLEGRO_KEY_RIGHT:
263 key[KEY_RIGHT] = true;
264 break;
265 }
266 }
267 }
268 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
269 switch(ev.keyboard.keycode) {
270 case ALLEGRO_KEY_UP:
271 key[KEY_UP] = false;
272 break;
273
274 case ALLEGRO_KEY_DOWN:
275 key[KEY_DOWN] = false;
276 break;
277
278 case ALLEGRO_KEY_LEFT:
279 key[KEY_LEFT] = false;
280 break;
281
282 case ALLEGRO_KEY_RIGHT:
283 key[KEY_RIGHT] = false;
284 break;
285
286 case ALLEGRO_KEY_ESCAPE:
287 doexit = true;
288 break;
289 }
290 }
291
292 if(redraw && al_is_event_queue_empty(event_queue)) {
293 redraw = false;
294
295 al_clear_to_color(al_map_rgb(0,0,0));
296
297 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
298
299 chatConsole.draw(font, al_map_rgb(255,255,255));
300
301 al_flip_display();
302 }
303 }
304
305 #if defined WINDOWS
306 closesocket(sock);
307 #elif defined LINUX
308 close(sock);
309 #endif
310
311 shutdownWinSock();
312
313 al_destroy_event_queue(event_queue);
314 al_destroy_bitmap(bouncer);
315 al_destroy_display(display);
316 al_destroy_timer(timer);
317
318 return 0;
319}
320
321void initWinSock()
322{
323#if defined WINDOWS
324 WORD wVersionRequested;
325 WSADATA wsaData;
326 int wsaerr;
327
328 wVersionRequested = MAKEWORD(2, 2);
329 wsaerr = WSAStartup(wVersionRequested, &wsaData);
330
331 if (wsaerr != 0) {
332 cout << "The Winsock dll not found." << endl;
333 exit(1);
334 }else
335 cout << "The Winsock dll was found." << endl;
336#endif
337}
338
339void shutdownWinSock()
340{
341#if defined WINDOWS
342 WSACleanup();
343#endif
344}
345
346// need to make a function like this that works on windows
347void error(const char *msg)
348{
349 perror(msg);
350 shutdownWinSock();
351 exit(1);
352}
Note: See TracBrowser for help on using the repository browser.