Project

General

Profile

Statistics
| Revision:

root / proj / src / proj.c @ 303

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