Project

General

Profile

Statistics
| Revision:

root / proj / src / proj.c @ 302

History | View | Annotate | Download (30.1 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 302 up20180642
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player, 1); 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 302 up20180642
    gunner_t *shooter2 = gunner_ctor(bsp_shooter, bsp_nothing, gunner_player, 2);
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 302 up20180642
                               bullet_draw_list(bullet_list);
347 295 up20180642
                               gunner_draw_list(shooter_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 302 up20180642
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player, 1); if(shooter1 == NULL) printf("Failed to get shooter1\n");
428 301 up20180642
    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 302 up20180642
    int dead = false;
448 301 up20180642
449
    int health = 50;
450
451 302 up20180642
    while (good && !dead) {
452 301 up20180642
       /* Get a request message. */
453
       if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
454
           printf("driver_receive failed with %d", r);
455
           continue;
456
       }
457
       if (is_ipc_notify(ipc_status)) { /* received notification */
458
           switch (_ENDPOINT_P(msg.m_source)) {
459
               case HARDWARE: /* hardware interrupt notification */
460
                   for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
461
                       if (msg.m_notify.interrupts & n) {
462
                           interrupt_handler(i);
463
                           switch (i) {
464
                           case TIMER0_IRQ: //printf("L463\n");
465
466
                               if (no_interrupts % 60 == 0) timer_update(in_game_timer);//printf("L465\n");
467
                               update_movement(map1, shooter1, keys, shooter_list);//printf("L466\n");
468
469
                               update_game_state(map1, shooter_list, bullet_list);//printf("L468\n");
470
471 302 up20180642
                               if(list_find(shooter_list, shooter1) == list_end(shooter_list)){ printf("YOU DIED\n");
472
                                   good = false;
473
                                   dead = true;
474
                                   break;
475
                               } //printf("L489\n");
476
477 301 up20180642
                               //update_scale();
478
                               double angle = get_mouse_angle(shooter1);//printf("L471\n");
479
                               gunner_set_angle(shooter1, angle - M_PI_2); //printf("L472\n");
480
481
                               ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
482
                                              gunner_get_y(shooter1)-ent_get_YLength()/2.0);
483
484
                               while(list_size(shooter_list) < ZOMBIES_NUM){
485 302 up20180642
                                   gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_meelee, 3);
486 301 up20180642
                                   gunner_set_health(zombie, health);
487
                                   gunner_set_curr_health(zombie, health);
488
                                   health *= ZOMBIE_HEALTH_FACTOR;
489
                                   get_random_spawn(map1, zombie);
490
                                   list_push_back(shooter_list, zombie);
491
                               } //printf("L484\n");
492
493
                               graph_clear_screen();
494
                               map_draw   (map1);
495 302 up20180642
                               bullet_draw_list(bullet_list);
496 301 up20180642
                               gunner_draw_list(shooter_list);
497
498
                               text_draw(in_game_timer->text);
499
500
                               sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
501
                               sprite_draw(sp_crosshair);
502
                               graph_draw(); //printf("L508\n");
503
504
                               break;
505
                           case KBC_IRQ:
506
                               if ((scancode[0]) == ESC_BREAK_CODE) {
507
                                   good = false;
508
                                   // reset game
509
                                   while(list_size(bullet_list) > 0){
510
                                       bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
511
                                       bullet_dtor(p);
512
                                   }
513
                                   list_node_t *it = list_begin(shooter_list);
514
                                   while (it != list_end(shooter_list)) {
515
                                       gunner_t *p = *(gunner_t**)list_node_val(it);
516
                                       get_random_spawn(map1, p);
517
                                       gunner_set_curr_health(p, gunner_get_health(p));
518
                                       it = list_node_next(it);
519
                                   }
520
                                   timer_reset(in_game_timer);
521
                               }
522
                               break;
523
                           case MOUSE_IRQ:
524
                               if (counter_mouse_ih >= 3) {
525
                                   mouse_parse_packet(packet_mouse_ih, &pp);
526
                                   update_mouse(&pp);
527
                                   if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
528
                                       shoot_bullet(shooter1, bullet_list, bsp_bullet);
529
                                   last_lb = keys->lb_pressed;
530
                                   counter_mouse_ih = 0;
531
532
                               }
533
                               break;
534
                           case COM1_IRQ: nctp_ih(); break;
535
                           }
536
                       }
537
                   }
538
                   break;
539
               default:
540
                   break; /* no other notifications expected: do nothing */
541
           }
542
       } else { /* received standart message, not a notification */
543
           /* no standart message expected: do nothing */
544
       }
545
    }
546
547
    while(list_size(shooter_list) > 0){
548
        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
549
        gunner_dtor(p);
550
    }
551
    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
552
553 295 up20180642
    while(list_size(bullet_list) > 0){
554
        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
555
        bullet_dtor(p);
556
    }
557
    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
558
559 302 up20180642
    if(dead){
560
        printf("YOU DIED\n");
561
    }
562
563 295 up20180642
    timer_dtor(in_game_timer); in_game_timer = NULL;
564
565 294 up20180642
    return SUCCESS;
566
}
567 296 up20180642
568 298 up20180642
#define CHAT_MAX_SIZE   75
569
#define CHAT_MAX_NUM    19
570 297 up20180642
text_t      *t_text[CHAT_MAX_NUM] = {NULL};
571
rectangle_t *r_text               =  NULL;
572
static void chat_process(const uint8_t *p, const size_t sz){
573
    char buffer2[CHAT_MAX_NUM+3];
574
    void *dest = NULL;
575
    hltp_type tp = hltp_interpret(p, sz, &dest);
576
    switch(tp){
577
        case hltp_type_string:
578
            strcpy(buffer2, dest);
579
            strncat(buffer2, " <", 2);
580
            for(size_t i = CHAT_MAX_NUM-1; i; --i)
581
                text_set_text(t_text[i], text_get_string(t_text[i-1]));
582
            text_set_text(t_text[0], buffer2);
583
            for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
584
                if(text_get_string(t_text[i])[0] == '>'){
585
                    text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
586
                    text_set_halign(t_text[i], text_halign_left);
587
                }else{
588
                    text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
589
                    text_set_halign(t_text[i], text_halign_right);
590
                }
591
            }
592
            break;
593
        default: break;
594
    }
595
}
596 300 up20180642
static int (chat)(void){
597 297 up20180642
    int r;
598
599 298 up20180642
    nctp_dump();
600 297 up20180642
    nctp_set_processor(chat_process);
601
602
    struct packet pp;
603
604 298 up20180642
    char buffer[CHAT_MAX_SIZE] = "";
605 297 up20180642
    rectangle_t *r_buffer = NULL; {
606 298 up20180642
        r_buffer = rectangle_ctor(0,0,900,70);
607 297 up20180642
        rectangle_set_pos(r_buffer, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
608 298 up20180642
                                    graph_get_YRes()*0.87-rectangle_get_h(r_buffer)/2);
609 297 up20180642
        rectangle_set_fill_color   (r_buffer, GRAPH_BLACK);
610
        rectangle_set_outline_width(r_buffer, 2);
611
        rectangle_set_outline_color(r_buffer, GRAPH_WHITE);
612
        rectangle_set_fill_trans(r_buffer, GRAPH_TRANSPARENT);
613
    }
614
    text_t      *t_buffer = NULL; {
615
        t_buffer = text_ctor(consolas, "");
616
        text_set_pos(t_buffer, rectangle_get_x(r_buffer)+50,
617
                               rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)/2);
618
        text_set_halign(t_buffer, text_halign_left);
619
        text_set_valign(t_buffer, text_valign_center);
620
        text_set_color (t_buffer, TEXT_COLOR);
621
    }
622 298 up20180642
    text_t      *t_size   = NULL; {
623
        t_size = text_ctor(consolas, "");
624
        text_set_pos(t_size, rectangle_get_x(r_buffer)+rectangle_get_w(r_buffer)-5,
625
                             rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)-5);
626
        text_set_halign(t_size, text_halign_right);
627
        text_set_valign(t_size, text_valign_bottom);
628
        text_set_color (t_size, TEXT_COLOR);
629
        text_set_size  (t_size, 18);
630
        char buffer2[20];
631
        sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
632
        text_set_text(t_size, buffer2);
633
    }
634 297 up20180642
635
    /** r_text */ {
636 298 up20180642
        r_text = rectangle_ctor(0,0,900,550);
637 297 up20180642
        rectangle_set_pos(r_text, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
638 298 up20180642
                                  graph_get_YRes()*0.09);
639 297 up20180642
        rectangle_set_fill_color   (r_text, GRAPH_BLACK);
640
        rectangle_set_outline_width(r_text, 2);
641
        rectangle_set_outline_color(r_text, GRAPH_WHITE);
642
        rectangle_set_fill_trans(r_text, GRAPH_TRANSPARENT);
643
    }
644
    /** t_text */ {
645
        for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
646
            t_text[i] = text_ctor(consolas, " ");
647
            text_set_pos(t_text[i], rectangle_get_x(r_text)+50,
648 298 up20180642
                                       rectangle_get_y(r_text)+rectangle_get_h(r_text)-30-25*i);
649 297 up20180642
            text_set_halign(t_text[i], text_halign_left);
650
            text_set_valign(t_text[i], text_valign_bottom);
651
            text_set_color (t_text[i], TEXT_COLOR);
652
        }
653
    }
654
655
    /// loop stuff
656
    int ipc_status;
657
    message msg;
658
    int good = true;
659
    while (good) {
660
        /* Get a request message. */
661
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
662
            printf("driver_receive failed with %d", r);
663
            continue;
664
        }
665
        if (is_ipc_notify(ipc_status)) { /* received notification */
666
            switch (_ENDPOINT_P(msg.m_source)) {
667
                case HARDWARE: /* hardware interrupt notification */
668
                    for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
669
                        if (msg.m_notify.interrupts & n) {
670
                            interrupt_handler(i);
671
                            switch (i) {
672
                            case TIMER0_IRQ:
673
                                graph_clear_screen();
674
                                sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
675
676
                                rectangle_draw(r_buffer);
677
                                text_draw(t_buffer);
678 298 up20180642
                                text_draw(t_size);
679 297 up20180642
680
                                rectangle_draw(r_text);
681
                                for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_draw(t_text[i]);
682
683
                                sprite_draw(sp_crosshair);
684
                                graph_draw();
685
                                break;
686
                            case KBC_IRQ:
687 298 up20180642
                                if      (scancode[0] == ESC_BREAK_CODE) good = false;
688
                                else if (scancode[0] == ENTER_MAKE_CODE) {
689 297 up20180642
                                    hltp_send_string(buffer);
690
                                    char buffer2[CHAT_MAX_SIZE+3] = "> ";
691
                                    strncat(buffer2, buffer, strlen(buffer));
692
                                    for(size_t i = CHAT_MAX_NUM-1; i; --i)
693
                                        text_set_text(t_text[i], text_get_string(t_text[i-1]));
694
                                    text_set_text(t_text[0], buffer2);
695
                                    for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
696
                                        if(text_get_string(t_text[i])[0] == '>'){
697
                                            text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
698
                                            text_set_halign(t_text[i], text_halign_left);
699
                                        }else{
700
                                            text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
701
                                            text_set_halign(t_text[i], text_halign_right);
702
                                        }
703
                                    }
704
                                    buffer[0] = '\0';
705 298 up20180642
                                } else if(scancode[0] == BACKSPACE_MAKE_CODE){
706
                                    buffer[strlen(buffer)-1] = '\0';
707
                                } else {
708 297 up20180642
                                    char c = map_makecode(scancode[0]);
709
                                    if (c == ERROR_CODE) break;
710
                                    if(strlen(buffer) < CHAT_MAX_SIZE) strncat(buffer, &c, 1);
711 298 up20180642
                                    else                               printf("Char limit exceeded\n");
712 297 up20180642
                                }
713 298 up20180642
                                text_set_text(t_buffer, buffer);
714
                                char buffer2[20];
715
                                sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
716
                                text_set_text(t_size, buffer2);
717 297 up20180642
                            case MOUSE_IRQ:
718
                                if (counter_mouse_ih >= 3) {
719
                                    mouse_parse_packet(packet_mouse_ih, &pp);
720
                                    update_mouse(&pp);
721
                                    counter_mouse_ih = 0;
722
                                }
723
                                break;
724 298 up20180642
                            case COM1_IRQ: nctp_ih(); break;
725 297 up20180642
                            }
726
                        }
727
                    }
728
                    break;
729
                default:
730
                    break; /* no other notifications expected: do nothing */
731
            }
732
        } else { /* received standart message, not a notification */
733
            /* no standart message expected: do nothing */
734
        }
735
    }
736
737
    rectangle_dtor(r_buffer);
738
    text_dtor     (t_buffer);
739
740
    rectangle_dtor(r_text);
741
    for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_dtor(t_text[i]);
742
743 298 up20180642
    nctp_set_processor(NULL);
744
745 296 up20180642
    return SUCCESS;
746
}