Project

General

Profile

Statistics
| Revision:

root / proj / src / proj.c @ 301

History | View | Annotate | Download (30 KB)

1 144 up20180655
#include <lcom/lcf.h>
2
#include <lcom/proj.h>
3
#include <lcom/liblm.h>
4 185 up20180655
#include <math.h>
5 144 up20180655
6 149 up20180655
#include "proj_macros.h"
7 179 up20180642
#include "proj_func.h"
8 147 up20180655
9 149 up20180655
#include "kbc.h"
10
#include "timer.h"
11
#include "keyboard.h"
12 150 up20180655
#include "mouse.h"
13 189 up20180655
#include "graph.h"
14 291 up20180642
#include "menu.h"
15 234 up20180655
#include "rtc.h"
16 287 up20180642
#include "hltp.h"
17 153 up20180655
#include "interrupts_func.h"
18 270 up20180655
#include "makecode_map.h"
19 149 up20180655
20 179 up20180642
#include "graph.h"
21
#include "rectangle.h"
22 182 up20180642
#include "font.h"
23 192 up20180642
#include "ent.h"
24 168 up20180642
25 192 up20180642
#include "crosshair.h"
26
#include "shooter.h"
27
#include "pistol.h"
28
#include "nothing.h"
29 237 up20180642
#include "bullet.h"
30 216 up20180642
#include "map1.h"
31 183 up20180642
32 294 up20180642
#include "errors.h"
33
34 226 up20180642
#include "list.h"
35
36 144 up20180655
int main(int argc, char* argv[]) {
37
38
    lcf_set_language("EN-US");
39
40 235 up20180642
    lcf_trace_calls("/home/lcom/labs/proj/trace.txt");
41 144 up20180655
42 189 up20180655
    lcf_log_output("/home/lcom/labs/proj/output.txt");
43 144 up20180655
44
    if (lcf_start(argc, argv)) return 1;
45
46
    lcf_cleanup();
47
48
    return 0;
49
}
50 147 up20180655
51 294 up20180642
font_t               *consolas      = NULL;
52
basic_sprite_t       *bsp_crosshair = NULL;
53
basic_sprite_t       *bsp_shooter   = NULL;
54 301 up20180642
basic_sprite_t       *bsp_zombie    = NULL;
55 294 up20180642
basic_sprite_t       *bsp_pistol    = NULL;
56
basic_sprite_t       *bsp_nothing   = NULL;
57
basic_sprite_t       *bsp_bullet    = NULL;
58
map_t                *map1          = NULL;
59
sprite_t             *sp_crosshair  = NULL;
60
61 300 up20180642
static int (singleplayer)(void);
62
static int (chat)(void);
63 149 up20180655
int(proj_main_loop)(int argc, char *argv[]) {
64 170 up20180642
65
    int r;
66
67 294 up20180642
    consolas = font_ctor("/home/lcom/labs/proj/media/font/Consolas/xpm2");
68 261 up20180642
    if(consolas == NULL){ printf("Failed to load consolas\n"); return 1; }
69 192 up20180642
70 261 up20180642
    /// subscribe interrupts
71
    if (subscribe_all()) { return 1; }
72 170 up20180642
73 297 up20180642
    /// initialize graphics
74
    if(graph_init(GRAPH_MODE)){
75
        printf("%s: failed to initalize graphics.\n", __func__);
76
        if (cleanup()) printf("%s: failed to cleanup.\n", __func__);
77
        return 1;
78
    }
79 152 up20180642
80 261 up20180642
    /// Load stuff
81
    {
82 297 up20180642
        graph_clear_screen();
83
        text_t *txt = text_ctor(consolas, "Loading...");
84
        text_draw(txt);
85
        text_dtor(txt);
86
        graph_draw();
87 183 up20180642
88 261 up20180642
        bsp_crosshair = get_crosshair(); if(bsp_crosshair == NULL) printf("Failed to get crosshair\n");
89
        bsp_shooter   = get_shooter  (); if(bsp_shooter   == NULL) printf("Failed to get shooter\n");
90 301 up20180642
        bsp_zombie    = bsp_shooter;     if(bsp_zombie    == NULL) printf("Failed to get zombie\n");
91 261 up20180642
        bsp_pistol    = get_pistol   (); if(bsp_pistol    == NULL) printf("Failed to get pistol\n");
92
        bsp_nothing   = get_nothing  (); if(bsp_nothing   == NULL) printf("Failed to get nothing\n");
93
        bsp_bullet    = get_bullet   (); if(bsp_bullet    == NULL) printf("Failed to get bullet\n");
94
        map1          = get_map1     (); if(map1          == NULL) printf("Failed to get map1\n");
95 226 up20180642
96 261 up20180642
        sp_crosshair = sprite_ctor(bsp_crosshair); if(sp_crosshair == NULL) printf("Failed to get crosshair sprite\n");
97
    }
98 226 up20180642
99 297 up20180642
    menu_t *main_menu = menu_ctor(consolas);
100 299 up20180642
    menu_add_item(main_menu, "Single player");
101
    menu_add_item(main_menu, "Multiplayer");
102 297 up20180642
    menu_add_item(main_menu, "Chat");
103
    menu_add_item(main_menu, "Exit");
104 234 up20180655
105 297 up20180642
    //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
106
    uint8_t last_lb = 0;
107
    struct packet pp;
108
    keys_t *keys = get_key_presses();
109
110 261 up20180642
    /// loop stuff
111
    int ipc_status;
112
    message msg;
113 267 up20180655
114 297 up20180642
    int click = 0;
115 267 up20180655
116 295 up20180642
    int good = true;
117
118
    while (good) {
119 261 up20180642
        /* Get a request message. */
120
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
121
            printf("driver_receive failed with %d", r);
122
            continue;
123
        }
124
        if (is_ipc_notify(ipc_status)) { /* received notification */
125
            switch (_ENDPOINT_P(msg.m_source)) {
126
                case HARDWARE: /* hardware interrupt notification */
127
                    for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
128
                        if (msg.m_notify.interrupts & n) {
129
                            interrupt_handler(i);
130
                            switch (i) {
131
                            case TIMER0_IRQ:
132 192 up20180642
133 295 up20180642
                                graph_clear_screen();
134
                                switch(menu_update_state(main_menu, click)){
135
                                    case -1: break;
136 300 up20180642
                                    case  0: singleplayer(); break; //campaign(); break;
137 299 up20180642
                                    case  1: break;
138
                                    case  2: chat(); break;
139
                                    case  3: good = false; break;
140 295 up20180642
                                }
141
                                menu_draw(main_menu);
142 192 up20180642
143 295 up20180642
                                click = 0;
144 202 up20180655
145 295 up20180642
                                sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
146
                                sprite_draw(sp_crosshair);
147
                                graph_draw();
148 231 up20180655
149 261 up20180642
                                break;
150
                            case KBC_IRQ:
151 295 up20180642
                                if ((scancode[0]) == ESC_BREAK_CODE) good = false;
152 261 up20180642
                            case MOUSE_IRQ:
153
                                if (counter_mouse_ih >= 3) {
154
                                    mouse_parse_packet(packet_mouse_ih, &pp);
155
                                    update_mouse(&pp);
156 295 up20180642
                                    if (!click) click = last_lb ^ keys->lb_pressed && keys->lb_pressed;
157 261 up20180642
                                    last_lb = keys->lb_pressed;
158
                                    counter_mouse_ih = 0;
159 220 up20180655
                                }
160 261 up20180642
                                break;
161 298 up20180642
                            case COM1_IRQ: nctp_ih(); break;
162 220 up20180655
                            }
163 251 up20180655
                        }
164 261 up20180642
                    }
165 167 up20180655
166 261 up20180642
                    break;
167
                default:
168
                    break; /* no other notifications expected: do nothing */
169 147 up20180655
            }
170 261 up20180642
        } else { /* received standart message, not a notification */
171
            /* no standart message expected: do nothing */
172 147 up20180655
        }
173 261 up20180642
    }
174 149 up20180655
175 261 up20180642
    basic_sprite_dtor      (bsp_crosshair); bsp_crosshair = NULL;
176
    basic_sprite_dtor      (bsp_shooter  ); bsp_shooter   = NULL;
177 301 up20180642
    /*basic_sprite_dtor      (bsp_zombie   );*/ bsp_zombie    = NULL;
178 261 up20180642
    sprite_dtor            (sp_crosshair ); sp_crosshair  = NULL;
179
    basic_sprite_dtor      (bsp_pistol   ); bsp_pistol    = NULL;
180
    basic_sprite_dtor      (bsp_nothing  ); bsp_nothing   = NULL;
181
    map_dtor               (map1         ); map1          = NULL;
182
    font_dtor              (consolas     ); consolas      = NULL;
183 243 up20180642
184 261 up20180642
    // Unsubscribe interrupts
185
    if (unsubscribe_all()) {
186
        if (cleanup())
187
            printf("%s: failed to cleanup.\n", __func__);
188
        return 1;
189
    }
190 188 up20180642
191 261 up20180642
    if (cleanup()) {
192
        printf("%s: failed to cleanup.\n", __func__);
193
        return 1;
194
    }
195 155 up20180655
196 149 up20180655
    return 0;
197 147 up20180655
}
198 294 up20180642
199 300 up20180642
static int (campaign)(void);
200 301 up20180642
static int (zombies)(void);
201 300 up20180642
static int (singleplayer)(void) {
202
203 295 up20180642
    int r;
204
205 300 up20180642
    menu_t *main_menu = menu_ctor(consolas);
206
    menu_add_item(main_menu, "Campaign");
207
    menu_add_item(main_menu, "Zombies");
208
    menu_add_item(main_menu, "Back");
209
210
    //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
211
    uint8_t last_lb = 0;
212
    struct packet pp;
213
    keys_t *keys = get_key_presses();
214
215
    /// loop stuff
216
    int ipc_status;
217
    message msg;
218
219
    int click = 0;
220
221
    int good = true;
222
223
    while (good) {
224
        /* Get a request message. */
225
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
226
            printf("driver_receive failed with %d", r);
227
            continue;
228
        }
229
        if (is_ipc_notify(ipc_status)) { /* received notification */
230
            switch (_ENDPOINT_P(msg.m_source)) {
231
                case HARDWARE: /* hardware interrupt notification */
232
                    for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
233
                        if (msg.m_notify.interrupts & n) {
234
                            interrupt_handler(i);
235
                            switch (i) {
236
                            case TIMER0_IRQ:
237
238
                                graph_clear_screen();
239
                                switch(menu_update_state(main_menu, click)){
240
                                    case -1: break;
241
                                    case  0: campaign(); break;
242 301 up20180642
                                    case  1: zombies(); break;
243 300 up20180642
                                    case  2: good = false; break;
244
                                }
245
                                menu_draw(main_menu);
246
247
                                click = 0;
248
249
                                sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
250
                                sprite_draw(sp_crosshair);
251
                                graph_draw();
252
253
                                break;
254
                            case KBC_IRQ:
255
                                if ((scancode[0]) == ESC_BREAK_CODE) good = false;
256
                            case MOUSE_IRQ:
257
                                if (counter_mouse_ih >= 3) {
258
                                    mouse_parse_packet(packet_mouse_ih, &pp);
259
                                    update_mouse(&pp);
260
                                    if (!click) click = last_lb ^ keys->lb_pressed && keys->lb_pressed;
261
                                    last_lb = keys->lb_pressed;
262
                                    counter_mouse_ih = 0;
263
                                }
264
                                break;
265
                            case COM1_IRQ: nctp_ih(); break;
266
                            }
267
                        }
268
                    }
269
270
                    break;
271
                default:
272
                    break; /* no other notifications expected: do nothing */
273
            }
274
        } else { /* received standart message, not a notification */
275
            /* no standart message expected: do nothing */
276
        }
277
    }
278
279
    return 0;
280
}
281
282
static int (campaign)(void){
283
284
    int r;
285
286 295 up20180642
    ent_set_scale(DEFAULT_SCALE);
287
    text_timer_t *in_game_timer = timer_ctor(consolas);
288
289
    list_t *shooter_list = list_ctor();
290
291 301 up20180642
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player); if(shooter1 == NULL) printf("Failed to get shooter1\n");
292 295 up20180642
    gunner_set_spawn(shooter1, 75, 75);
293
    gunner_set_pos(shooter1, 75, 75);
294
295 301 up20180642
    gunner_t *shooter2 = gunner_ctor(bsp_shooter, bsp_nothing, gunner_player);
296 295 up20180642
    gunner_set_spawn(shooter2, 975, 75);
297
    gunner_set_pos(shooter2, 775, 75);
298
299
    list_insert(shooter_list, list_end(shooter_list), shooter1);
300
    list_insert(shooter_list, list_end(shooter_list), shooter2);
301
302
    list_t *bullet_list  = list_ctor();
303
304
    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
305
                   gunner_get_y(shooter1)-ent_get_YLength()/2.0);
306
307
   //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
308
   uint8_t last_lb = 0;
309
   struct packet pp;
310
   keys_t *keys = get_key_presses();
311
312
    /// loop stuff
313
    int ipc_status;
314
    message msg;
315 296 up20180642
    int good = true;
316 295 up20180642
317 296 up20180642
    while (good) {
318 295 up20180642
       /* Get a request message. */
319
       if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
320
           printf("driver_receive failed with %d", r);
321
           continue;
322
       }
323
       if (is_ipc_notify(ipc_status)) { /* received notification */
324
           switch (_ENDPOINT_P(msg.m_source)) {
325
               case HARDWARE: /* hardware interrupt notification */
326
                   for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
327
                       if (msg.m_notify.interrupts & n) {
328
                           interrupt_handler(i);
329
                           switch (i) {
330
                           case TIMER0_IRQ:
331
332
                               if (no_interrupts % 60 == 0) timer_update(in_game_timer);
333
                               update_movement(map1, shooter1, keys, shooter_list);
334
335
                               update_game_state(map1, shooter_list, bullet_list);
336
337
                               //update_scale();
338
                               double angle = get_mouse_angle(shooter1);
339
                               gunner_set_angle(shooter1, angle - M_PI_2);
340
341
                               ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
342
                                              gunner_get_y(shooter1)-ent_get_YLength()/2.0);
343
344
                               graph_clear_screen();
345
                               map_draw   (map1);
346
                               gunner_draw_list(shooter_list);
347
                               bullet_draw_list(bullet_list);
348
349
                               text_draw(in_game_timer->text);
350
351
                               sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
352
                               sprite_draw(sp_crosshair);
353
                               graph_draw();
354
355
                               break;
356
                           case KBC_IRQ:
357
                               if ((scancode[0]) == ESC_BREAK_CODE) {
358 296 up20180642
                                   good = false;
359 295 up20180642
                                   // reset game
360
                                   while(list_size(bullet_list) > 0){
361
                                       bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
362
                                       bullet_dtor(p);
363
                                   }
364
                                   list_node_t *it = list_begin(shooter_list);
365
                                   while (it != list_end(shooter_list)) {
366
                                       gunner_t *p = *(gunner_t**)list_node_val(it);
367
                                       get_random_spawn(map1, p);
368
                                       gunner_set_curr_health(p, gunner_get_health(p));
369
                                       it = list_node_next(it);
370
                                   }
371
                                   timer_reset(in_game_timer);
372
                               }
373
                               break;
374
                           case MOUSE_IRQ:
375
                               if (counter_mouse_ih >= 3) {
376
                                   mouse_parse_packet(packet_mouse_ih, &pp);
377
                                   update_mouse(&pp);
378
                                   if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
379
                                       shoot_bullet(shooter1, bullet_list, bsp_bullet);
380
                                   last_lb = keys->lb_pressed;
381
                                   counter_mouse_ih = 0;
382
383
                               }
384
                               break;
385 298 up20180642
                           case COM1_IRQ: nctp_ih(); break;
386 295 up20180642
                           }
387
                       }
388
                   }
389
                   break;
390
               default:
391
                   break; /* no other notifications expected: do nothing */
392
           }
393
       } else { /* received standart message, not a notification */
394
           /* no standart message expected: do nothing */
395
       }
396
    }
397
398
    while(list_size(shooter_list) > 0){
399
        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
400
        gunner_dtor(p);
401
    }
402 296 up20180642
    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
403 295 up20180642
404 301 up20180642
    while(list_size(bullet_list) > 0){
405
        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
406
        bullet_dtor(p);
407
    }
408
    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
409
410
    timer_dtor(in_game_timer); in_game_timer = NULL;
411
412
    return SUCCESS;
413
}
414
415
#define ZOMBIES_NUM             5
416
#define ZOMBIE_HEALTH_FACTOR    1.1
417
418
static int (zombies)(void){
419
420
    int r;
421
422
    ent_set_scale(DEFAULT_SCALE);
423
    text_timer_t *in_game_timer = timer_ctor(consolas);
424
425
    list_t *shooter_list = list_ctor();
426
427
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player); if(shooter1 == NULL) printf("Failed to get shooter1\n");
428
    gunner_set_spawn(shooter1, 75, 75);
429
    gunner_set_pos(shooter1, 75, 75);
430
431
    list_insert(shooter_list, list_end(shooter_list), shooter1);
432
433
    list_t *bullet_list  = list_ctor();
434
435
    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
436
                   gunner_get_y(shooter1)-ent_get_YLength()/2.0);
437
438
   //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
439
   uint8_t last_lb = 0;
440
   struct packet pp;
441
   keys_t *keys = get_key_presses();
442
443
    /// loop stuff
444
    int ipc_status;
445
    message msg;
446
    int good = true;
447
448
    int health = 50;
449
450
    while (good) {
451
       /* Get a request message. */
452
       if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
453
           printf("driver_receive failed with %d", r);
454
           continue;
455
       }
456
       if (is_ipc_notify(ipc_status)) { /* received notification */
457
           switch (_ENDPOINT_P(msg.m_source)) {
458
               case HARDWARE: /* hardware interrupt notification */
459
                   for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
460
                       if (msg.m_notify.interrupts & n) {
461
                           interrupt_handler(i);
462
                           switch (i) {
463
                           case TIMER0_IRQ: //printf("L463\n");
464
465
                               if (no_interrupts % 60 == 0) timer_update(in_game_timer);//printf("L465\n");
466
                               update_movement(map1, shooter1, keys, shooter_list);//printf("L466\n");
467
468
                               update_game_state(map1, shooter_list, bullet_list);//printf("L468\n");
469
470
                               //update_scale();
471
                               double angle = get_mouse_angle(shooter1);//printf("L471\n");
472
                               gunner_set_angle(shooter1, angle - M_PI_2); //printf("L472\n");
473
474
                               ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
475
                                              gunner_get_y(shooter1)-ent_get_YLength()/2.0);
476
477
                               while(list_size(shooter_list) < ZOMBIES_NUM){
478
                                   gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_meelee);
479
                                   gunner_set_health(zombie, health);
480
                                   gunner_set_curr_health(zombie, health);
481
                                   health *= ZOMBIE_HEALTH_FACTOR;
482
                                   get_random_spawn(map1, zombie);
483
                                   list_push_back(shooter_list, zombie);
484
                               } //printf("L484\n");
485
486
                               if(list_find(shooter_list, shooter1) == list_end(shooter_list)){
487
                                   good = false;
488
                                   break;
489
                               } //printf("L489\n");
490
                               graph_clear_screen();
491
                               map_draw   (map1);
492
                               gunner_draw_list(shooter_list);
493
                               bullet_draw_list(bullet_list); //printf("L502\n");
494
495
                               text_draw(in_game_timer->text);
496
497
                               sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
498
                               sprite_draw(sp_crosshair);
499
                               graph_draw(); //printf("L508\n");
500
501
                               break;
502
                           case KBC_IRQ:
503
                               if ((scancode[0]) == ESC_BREAK_CODE) {
504
                                   good = false;
505
                                   // reset game
506
                                   while(list_size(bullet_list) > 0){
507
                                       bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
508
                                       bullet_dtor(p);
509
                                   }
510
                                   list_node_t *it = list_begin(shooter_list);
511
                                   while (it != list_end(shooter_list)) {
512
                                       gunner_t *p = *(gunner_t**)list_node_val(it);
513
                                       get_random_spawn(map1, p);
514
                                       gunner_set_curr_health(p, gunner_get_health(p));
515
                                       it = list_node_next(it);
516
                                   }
517
                                   timer_reset(in_game_timer);
518
                               }
519
                               break;
520
                           case MOUSE_IRQ:
521
                               if (counter_mouse_ih >= 3) {
522
                                   mouse_parse_packet(packet_mouse_ih, &pp);
523
                                   update_mouse(&pp);
524
                                   if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
525
                                       shoot_bullet(shooter1, bullet_list, bsp_bullet);
526
                                   last_lb = keys->lb_pressed;
527
                                   counter_mouse_ih = 0;
528
529
                               }
530
                               break;
531
                           case COM1_IRQ: nctp_ih(); break;
532
                           }
533
                       }
534
                   }
535
                   break;
536
               default:
537
                   break; /* no other notifications expected: do nothing */
538
           }
539
       } else { /* received standart message, not a notification */
540
           /* no standart message expected: do nothing */
541
       }
542
    }
543
544
    while(list_size(shooter_list) > 0){
545
        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
546
        gunner_dtor(p);
547
    }
548
    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
549
550 295 up20180642
    while(list_size(bullet_list) > 0){
551
        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
552
        bullet_dtor(p);
553
    }
554
    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
555
556
    timer_dtor(in_game_timer); in_game_timer = NULL;
557
558 294 up20180642
    return SUCCESS;
559
}
560 296 up20180642
561 298 up20180642
#define CHAT_MAX_SIZE   75
562
#define CHAT_MAX_NUM    19
563 297 up20180642
text_t      *t_text[CHAT_MAX_NUM] = {NULL};
564
rectangle_t *r_text               =  NULL;
565
static void chat_process(const uint8_t *p, const size_t sz){
566
    char buffer2[CHAT_MAX_NUM+3];
567
    void *dest = NULL;
568
    hltp_type tp = hltp_interpret(p, sz, &dest);
569
    switch(tp){
570
        case hltp_type_string:
571
            strcpy(buffer2, dest);
572
            strncat(buffer2, " <", 2);
573
            for(size_t i = CHAT_MAX_NUM-1; i; --i)
574
                text_set_text(t_text[i], text_get_string(t_text[i-1]));
575
            text_set_text(t_text[0], buffer2);
576
            for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
577
                if(text_get_string(t_text[i])[0] == '>'){
578
                    text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
579
                    text_set_halign(t_text[i], text_halign_left);
580
                }else{
581
                    text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
582
                    text_set_halign(t_text[i], text_halign_right);
583
                }
584
            }
585
            break;
586
        default: break;
587
    }
588
}
589 300 up20180642
static int (chat)(void){
590 297 up20180642
    int r;
591
592 298 up20180642
    nctp_dump();
593 297 up20180642
    nctp_set_processor(chat_process);
594
595
    struct packet pp;
596
597 298 up20180642
    char buffer[CHAT_MAX_SIZE] = "";
598 297 up20180642
    rectangle_t *r_buffer = NULL; {
599 298 up20180642
        r_buffer = rectangle_ctor(0,0,900,70);
600 297 up20180642
        rectangle_set_pos(r_buffer, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
601 298 up20180642
                                    graph_get_YRes()*0.87-rectangle_get_h(r_buffer)/2);
602 297 up20180642
        rectangle_set_fill_color   (r_buffer, GRAPH_BLACK);
603
        rectangle_set_outline_width(r_buffer, 2);
604
        rectangle_set_outline_color(r_buffer, GRAPH_WHITE);
605
        rectangle_set_fill_trans(r_buffer, GRAPH_TRANSPARENT);
606
    }
607
    text_t      *t_buffer = NULL; {
608
        t_buffer = text_ctor(consolas, "");
609
        text_set_pos(t_buffer, rectangle_get_x(r_buffer)+50,
610
                               rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)/2);
611
        text_set_halign(t_buffer, text_halign_left);
612
        text_set_valign(t_buffer, text_valign_center);
613
        text_set_color (t_buffer, TEXT_COLOR);
614
    }
615 298 up20180642
    text_t      *t_size   = NULL; {
616
        t_size = text_ctor(consolas, "");
617
        text_set_pos(t_size, rectangle_get_x(r_buffer)+rectangle_get_w(r_buffer)-5,
618
                             rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)-5);
619
        text_set_halign(t_size, text_halign_right);
620
        text_set_valign(t_size, text_valign_bottom);
621
        text_set_color (t_size, TEXT_COLOR);
622
        text_set_size  (t_size, 18);
623
        char buffer2[20];
624
        sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
625
        text_set_text(t_size, buffer2);
626
    }
627 297 up20180642
628
    /** r_text */ {
629 298 up20180642
        r_text = rectangle_ctor(0,0,900,550);
630 297 up20180642
        rectangle_set_pos(r_text, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
631 298 up20180642
                                  graph_get_YRes()*0.09);
632 297 up20180642
        rectangle_set_fill_color   (r_text, GRAPH_BLACK);
633
        rectangle_set_outline_width(r_text, 2);
634
        rectangle_set_outline_color(r_text, GRAPH_WHITE);
635
        rectangle_set_fill_trans(r_text, GRAPH_TRANSPARENT);
636
    }
637
    /** t_text */ {
638
        for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
639
            t_text[i] = text_ctor(consolas, " ");
640
            text_set_pos(t_text[i], rectangle_get_x(r_text)+50,
641 298 up20180642
                                       rectangle_get_y(r_text)+rectangle_get_h(r_text)-30-25*i);
642 297 up20180642
            text_set_halign(t_text[i], text_halign_left);
643
            text_set_valign(t_text[i], text_valign_bottom);
644
            text_set_color (t_text[i], TEXT_COLOR);
645
        }
646
    }
647
648
    /// loop stuff
649
    int ipc_status;
650
    message msg;
651
    int good = true;
652
    while (good) {
653
        /* Get a request message. */
654
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
655
            printf("driver_receive failed with %d", r);
656
            continue;
657
        }
658
        if (is_ipc_notify(ipc_status)) { /* received notification */
659
            switch (_ENDPOINT_P(msg.m_source)) {
660
                case HARDWARE: /* hardware interrupt notification */
661
                    for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
662
                        if (msg.m_notify.interrupts & n) {
663
                            interrupt_handler(i);
664
                            switch (i) {
665
                            case TIMER0_IRQ:
666
                                graph_clear_screen();
667
                                sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
668
669
                                rectangle_draw(r_buffer);
670
                                text_draw(t_buffer);
671 298 up20180642
                                text_draw(t_size);
672 297 up20180642
673
                                rectangle_draw(r_text);
674
                                for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_draw(t_text[i]);
675
676
                                sprite_draw(sp_crosshair);
677
                                graph_draw();
678
                                break;
679
                            case KBC_IRQ:
680 298 up20180642
                                if      (scancode[0] == ESC_BREAK_CODE) good = false;
681
                                else if (scancode[0] == ENTER_MAKE_CODE) {
682 297 up20180642
                                    hltp_send_string(buffer);
683
                                    char buffer2[CHAT_MAX_SIZE+3] = "> ";
684
                                    strncat(buffer2, buffer, strlen(buffer));
685
                                    for(size_t i = CHAT_MAX_NUM-1; i; --i)
686
                                        text_set_text(t_text[i], text_get_string(t_text[i-1]));
687
                                    text_set_text(t_text[0], buffer2);
688
                                    for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
689
                                        if(text_get_string(t_text[i])[0] == '>'){
690
                                            text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
691
                                            text_set_halign(t_text[i], text_halign_left);
692
                                        }else{
693
                                            text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
694
                                            text_set_halign(t_text[i], text_halign_right);
695
                                        }
696
                                    }
697
                                    buffer[0] = '\0';
698 298 up20180642
                                } else if(scancode[0] == BACKSPACE_MAKE_CODE){
699
                                    buffer[strlen(buffer)-1] = '\0';
700
                                } else {
701 297 up20180642
                                    char c = map_makecode(scancode[0]);
702
                                    if (c == ERROR_CODE) break;
703
                                    if(strlen(buffer) < CHAT_MAX_SIZE) strncat(buffer, &c, 1);
704 298 up20180642
                                    else                               printf("Char limit exceeded\n");
705 297 up20180642
                                }
706 298 up20180642
                                text_set_text(t_buffer, buffer);
707
                                char buffer2[20];
708
                                sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
709
                                text_set_text(t_size, buffer2);
710 297 up20180642
                            case MOUSE_IRQ:
711
                                if (counter_mouse_ih >= 3) {
712
                                    mouse_parse_packet(packet_mouse_ih, &pp);
713
                                    update_mouse(&pp);
714
                                    counter_mouse_ih = 0;
715
                                }
716
                                break;
717 298 up20180642
                            case COM1_IRQ: nctp_ih(); break;
718 297 up20180642
                            }
719
                        }
720
                    }
721
                    break;
722
                default:
723
                    break; /* no other notifications expected: do nothing */
724
            }
725
        } else { /* received standart message, not a notification */
726
            /* no standart message expected: do nothing */
727
        }
728
    }
729
730
    rectangle_dtor(r_buffer);
731
    text_dtor     (t_buffer);
732
733
    rectangle_dtor(r_text);
734
    for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_dtor(t_text[i]);
735
736 298 up20180642
    nctp_set_processor(NULL);
737
738 296 up20180642
    return SUCCESS;
739
}