Project

General

Profile

Statistics
| Revision:

root / proj / src / proj.c @ 305

History | View | Annotate | Download (24.8 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 305 up20180642
                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 261 up20180642
                            case TIMER0_IRQ:
133 192 up20180642
134 305 up20180642
                            graph_clear_screen();
135
                            switch(menu_update_state(main_menu, click)){
136
                                case -1: break;
137
                                case  0: singleplayer(); break; //campaign(); break;
138
                                case  1: break;
139
                                case  2: chat(); break;
140
                                case  3: good = false; break;
141
                            }
142
                            menu_draw(main_menu);
143 192 up20180642
144 305 up20180642
                            click = 0;
145 202 up20180655
146 305 up20180642
                            sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
147
                            sprite_draw(sp_crosshair);
148
                            graph_draw();
149 231 up20180655
150 305 up20180642
                            break;
151 261 up20180642
                            case KBC_IRQ:
152 305 up20180642
                            if ((scancode[0]) == ESC_BREAK_CODE) good = false;
153 261 up20180642
                            case MOUSE_IRQ:
154 305 up20180642
                            if (counter_mouse_ih >= 3) {
155
                                mouse_parse_packet(packet_mouse_ih, &pp);
156
                                update_mouse(&pp);
157
                                if (!click) click = last_lb ^ keys->lb_pressed && keys->lb_pressed;
158
                                last_lb = keys->lb_pressed;
159
                                counter_mouse_ih = 0;
160
                            }
161
                            break;
162 298 up20180642
                            case COM1_IRQ: nctp_ih(); break;
163 251 up20180655
                        }
164 261 up20180642
                    }
165 305 up20180642
                }
166 167 up20180655
167 305 up20180642
                break;
168 261 up20180642
                default:
169 305 up20180642
                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 305 up20180642
        printf("%s: failed to cleanup.\n", __func__);
189 261 up20180642
        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 click = 0;
218 304 up20180642
    uint32_t int_vector = 0;
219 300 up20180642
    int good = true;
220
    while (good) {
221
        /* Get a request message. */
222 304 up20180642
        if((r = get_interrupts_vector(&int_vector))) return r;
223
        for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
224
            if (int_vector & n) {
225
                interrupt_handler(i);
226
                switch (i) {
227 305 up20180642
                    case TIMER0_IRQ:
228 300 up20180642
229 304 up20180642
                    graph_clear_screen();
230
                    switch(menu_update_state(main_menu, click)){
231
                        case -1: break;
232
                        case  0: campaign(); break;
233
                        case  1: zombies(); break;
234
                        case  2: good = false; break;
235
                    }
236
                    menu_draw(main_menu);
237 300 up20180642
238 304 up20180642
                    click = 0;
239 300 up20180642
240 304 up20180642
                    sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
241
                    sprite_draw(sp_crosshair);
242
                    graph_draw();
243 300 up20180642
244 304 up20180642
                    break;
245 305 up20180642
                    case KBC_IRQ:
246 304 up20180642
                    if ((scancode[0]) == ESC_BREAK_CODE) good = false;
247 305 up20180642
                    case MOUSE_IRQ:
248 304 up20180642
                    if (counter_mouse_ih >= 3) {
249
                        mouse_parse_packet(packet_mouse_ih, &pp);
250
                        update_mouse(&pp);
251
                        if (!click) click = last_lb ^ keys->lb_pressed && keys->lb_pressed;
252
                        last_lb = keys->lb_pressed;
253
                        counter_mouse_ih = 0;
254 300 up20180642
                    }
255
                    break;
256 305 up20180642
                    case COM1_IRQ: nctp_ih(); break;
257 304 up20180642
                }
258 300 up20180642
            }
259
        }
260
    }
261
262
    return 0;
263
}
264
265
static int (campaign)(void){
266
267
    int r;
268
269 295 up20180642
    ent_set_scale(DEFAULT_SCALE);
270
    text_timer_t *in_game_timer = timer_ctor(consolas);
271
272
    list_t *shooter_list = list_ctor();
273
274 302 up20180642
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player, 1); if(shooter1 == NULL) printf("Failed to get shooter1\n");
275 295 up20180642
    gunner_set_spawn(shooter1, 75, 75);
276
    gunner_set_pos(shooter1, 75, 75);
277
278 302 up20180642
    gunner_t *shooter2 = gunner_ctor(bsp_shooter, bsp_nothing, gunner_player, 2);
279 295 up20180642
    gunner_set_spawn(shooter2, 975, 75);
280
    gunner_set_pos(shooter2, 775, 75);
281
282
    list_insert(shooter_list, list_end(shooter_list), shooter1);
283
    list_insert(shooter_list, list_end(shooter_list), shooter2);
284
285
    list_t *bullet_list  = list_ctor();
286
287
    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
288 305 up20180642
    gunner_get_y(shooter1)-ent_get_YLength()/2.0);
289 295 up20180642
290 305 up20180642
    //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
291
    uint8_t last_lb = 0;
292
    struct packet pp;
293
    keys_t *keys = get_key_presses();
294 295 up20180642
295
    /// loop stuff
296 304 up20180642
    uint32_t int_vector = 0;
297 296 up20180642
    int good = true;
298
    while (good) {
299 304 up20180642
        /* Get a request message. */
300
        if((r = get_interrupts_vector(&int_vector))) return r;
301
        for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
302 305 up20180642
            if (int_vector & n) {
303
                interrupt_handler(i);
304
                switch (i) {
305
                    case TIMER0_IRQ:
306 295 up20180642
307 305 up20180642
                    if (no_interrupts % 60 == 0) timer_update(in_game_timer);
308
                    update_movement(map1, shooter1, keys, shooter_list);
309 295 up20180642
310 305 up20180642
                    update_game_state(map1, shooter_list, bullet_list);
311 295 up20180642
312 305 up20180642
                    //update_scale();
313
                    double angle = get_mouse_angle(shooter1);
314
                    gunner_set_angle(shooter1, angle - M_PI_2);
315 295 up20180642
316 305 up20180642
                    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
317
                    gunner_get_y(shooter1)-ent_get_YLength()/2.0);
318 295 up20180642
319 305 up20180642
                    graph_clear_screen();
320
                    map_draw   (map1);
321
                    bullet_draw_list(bullet_list);
322
                    gunner_draw_list(shooter_list);
323 295 up20180642
324 305 up20180642
                    text_draw(in_game_timer->text);
325 295 up20180642
326 305 up20180642
                    sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
327
                    sprite_draw(sp_crosshair);
328
                    graph_draw();
329 295 up20180642
330 305 up20180642
                    break;
331
                    case KBC_IRQ:
332
                    if ((scancode[0]) == ESC_BREAK_CODE) {
333
                        good = false;
334
                        // reset game
335
                        while(list_size(bullet_list) > 0){
336
                            bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
337
                            bullet_dtor(p);
338
                        }
339
                        list_node_t *it = list_begin(shooter_list);
340
                        while (it != list_end(shooter_list)) {
341
                            gunner_t *p = *(gunner_t**)list_node_val(it);
342
                            get_random_spawn(map1, p);
343
                            gunner_set_curr_health(p, gunner_get_health(p));
344
                            it = list_node_next(it);
345
                        }
346
                        timer_reset(in_game_timer);
347
                    }
348
                    break;
349
                    case MOUSE_IRQ:
350
                    if (counter_mouse_ih >= 3) {
351
                        mouse_parse_packet(packet_mouse_ih, &pp);
352
                        update_mouse(&pp);
353
                        if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
354
                        shoot_bullet(shooter1, bullet_list, bsp_bullet);
355
                        last_lb = keys->lb_pressed;
356
                        counter_mouse_ih = 0;
357 304 up20180642
358 305 up20180642
                    }
359
                    break;
360
                    case COM1_IRQ: nctp_ih(); break;
361
                }
362
            }
363 304 up20180642
        }
364 295 up20180642
    }
365
366
    while(list_size(shooter_list) > 0){
367
        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
368
        gunner_dtor(p);
369
    }
370 296 up20180642
    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
371 295 up20180642
372 301 up20180642
    while(list_size(bullet_list) > 0){
373
        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
374
        bullet_dtor(p);
375
    }
376
    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
377
378
    timer_dtor(in_game_timer); in_game_timer = NULL;
379
380
    return SUCCESS;
381
}
382
383
#define ZOMBIES_NUM             5
384
#define ZOMBIE_HEALTH_FACTOR    1.1
385
386
static int (zombies)(void){
387
388
    int r;
389
390
    ent_set_scale(DEFAULT_SCALE);
391
    text_timer_t *in_game_timer = timer_ctor(consolas);
392
393
    list_t *shooter_list = list_ctor();
394
395 302 up20180642
    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player, 1); if(shooter1 == NULL) printf("Failed to get shooter1\n");
396 305 up20180642
    gunner_set_spawn(shooter1, 980, 790);
397
    gunner_set_pos(shooter1, 980, 790);
398 301 up20180642
399
    list_insert(shooter_list, list_end(shooter_list), shooter1);
400
401
    list_t *bullet_list  = list_ctor();
402
403
    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
404 305 up20180642
    gunner_get_y(shooter1)-ent_get_YLength()/2.0);
405 301 up20180642
406 305 up20180642
    //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
407
    uint8_t last_lb = 0;
408
    struct packet pp;
409
    keys_t *keys = get_key_presses();
410 301 up20180642
411
    /// loop stuff
412 304 up20180642
    uint32_t int_vector = 0;
413 301 up20180642
    int good = true;
414 302 up20180642
    int dead = false;
415 301 up20180642
416
    int health = 50;
417
418 302 up20180642
    while (good && !dead) {
419 304 up20180642
        /* Get a request message. */
420
        if((r = get_interrupts_vector(&int_vector))) return r;
421
        for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
422
            if (int_vector & n) {
423 305 up20180642
                interrupt_handler(i);
424
                switch (i) {
425
                    case TIMER0_IRQ:
426
                    if (no_interrupts % 60 == 0) timer_update(in_game_timer);
427 301 up20180642
428 305 up20180642
                    clock_t t1, t2;
429
                    t1 = clock();
430 301 up20180642
431 305 up20180642
                    update_movement(map1, shooter1, keys, shooter_list);
432 301 up20180642
433 305 up20180642
                    update_game_state(map1, shooter_list, bullet_list);
434 302 up20180642
435 305 up20180642
                    if(list_find(shooter_list, shooter1) == list_end(shooter_list)){
436
                        good = false;
437
                        dead = true;
438
                        break;
439
                    }
440 301 up20180642
441 305 up20180642
                    double angle = get_mouse_angle(shooter1);
442
                    gunner_set_angle(shooter1, angle - M_PI_2);
443 301 up20180642
444 305 up20180642
                    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
445
                                   gunner_get_y(shooter1)-ent_get_YLength()/2.0);
446 301 up20180642
447 305 up20180642
                    while(list_size(shooter_list) < ZOMBIES_NUM){
448
                        gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_melee | gunner_follow, 3);
449
                        gunner_set_health(zombie, health);
450
                        gunner_set_curr_health(zombie, health);
451
                        health *= ZOMBIE_HEALTH_FACTOR;
452
                        get_random_spawn(map1, zombie);
453
                        list_push_back(shooter_list, zombie);
454
                    }
455 301 up20180642
456 305 up20180642
                    graph_clear_screen();
457
                    map_draw   (map1);
458
                    bullet_draw_list(bullet_list);
459
                    gunner_draw_list(shooter_list);
460 301 up20180642
461 305 up20180642
                    text_draw(in_game_timer->text);
462 301 up20180642
463 305 up20180642
                    sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
464
                    sprite_draw(sp_crosshair);
465
                    graph_draw();
466 304 up20180642
467 305 up20180642
                    t2 = clock();
468
                    printf("%d microseconds\n", t2-t1);
469
470
                    break;
471
                    case KBC_IRQ:
472
                    if ((scancode[0]) == ESC_BREAK_CODE) {
473
                        good = false;
474
                        // reset game
475
                        while(list_size(bullet_list) > 0){
476
                            bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
477
                            bullet_dtor(p);
478
                        }
479
                        list_node_t *it = list_begin(shooter_list);
480
                        while (it != list_end(shooter_list)) {
481
                            gunner_t *p = *(gunner_t**)list_node_val(it);
482
                            get_random_spawn(map1, p);
483
                            gunner_set_curr_health(p, gunner_get_health(p));
484
                            it = list_node_next(it);
485
                        }
486
                        timer_reset(in_game_timer);
487
                    }
488
                    break;
489
                    case MOUSE_IRQ:
490
                    if (counter_mouse_ih >= 3) {
491
                        mouse_parse_packet(packet_mouse_ih, &pp);
492
                        update_mouse(&pp);
493
                        if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
494
                        shoot_bullet(shooter1, bullet_list, bsp_bullet);
495
                        last_lb = keys->lb_pressed;
496
                        counter_mouse_ih = 0;
497
498
                    }
499
                    break;
500
                    case COM1_IRQ: nctp_ih(); break;
501
                }
502
            }
503
        }
504 301 up20180642
    }
505
506
    while(list_size(shooter_list) > 0){
507
        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
508
        gunner_dtor(p);
509
    }
510
    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
511
512 295 up20180642
    while(list_size(bullet_list) > 0){
513
        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
514
        bullet_dtor(p);
515
    }
516
    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
517
518 302 up20180642
    if(dead){
519
        printf("YOU DIED\n");
520
    }
521
522 295 up20180642
    timer_dtor(in_game_timer); in_game_timer = NULL;
523
524 294 up20180642
    return SUCCESS;
525
}
526 296 up20180642
527 298 up20180642
#define CHAT_MAX_SIZE   75
528
#define CHAT_MAX_NUM    19
529 297 up20180642
text_t      *t_text[CHAT_MAX_NUM] = {NULL};
530
rectangle_t *r_text               =  NULL;
531
static void chat_process(const uint8_t *p, const size_t sz){
532
    char buffer2[CHAT_MAX_NUM+3];
533
    void *dest = NULL;
534
    hltp_type tp = hltp_interpret(p, sz, &dest);
535
    switch(tp){
536
        case hltp_type_string:
537 305 up20180642
        strcpy(buffer2, dest);
538
        strncat(buffer2, " <", 2);
539
        for(size_t i = CHAT_MAX_NUM-1; i; --i)
540
        text_set_text(t_text[i], text_get_string(t_text[i-1]));
541
        text_set_text(t_text[0], buffer2);
542
        for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
543
            if(text_get_string(t_text[i])[0] == '>'){
544
                text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
545
                text_set_halign(t_text[i], text_halign_left);
546
            }else{
547
                text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
548
                text_set_halign(t_text[i], text_halign_right);
549 297 up20180642
            }
550 305 up20180642
        }
551
        break;
552 297 up20180642
        default: break;
553
    }
554
}
555 300 up20180642
static int (chat)(void){
556 297 up20180642
    int r;
557
558 298 up20180642
    nctp_dump();
559 297 up20180642
    nctp_set_processor(chat_process);
560
561
    struct packet pp;
562
563 298 up20180642
    char buffer[CHAT_MAX_SIZE] = "";
564 297 up20180642
    rectangle_t *r_buffer = NULL; {
565 298 up20180642
        r_buffer = rectangle_ctor(0,0,900,70);
566 297 up20180642
        rectangle_set_pos(r_buffer, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
567 305 up20180642
        graph_get_YRes()*0.87-rectangle_get_h(r_buffer)/2);
568 297 up20180642
        rectangle_set_fill_color   (r_buffer, GRAPH_BLACK);
569
        rectangle_set_outline_width(r_buffer, 2);
570
        rectangle_set_outline_color(r_buffer, GRAPH_WHITE);
571
        rectangle_set_fill_trans(r_buffer, GRAPH_TRANSPARENT);
572
    }
573
    text_t      *t_buffer = NULL; {
574
        t_buffer = text_ctor(consolas, "");
575
        text_set_pos(t_buffer, rectangle_get_x(r_buffer)+50,
576 305 up20180642
        rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)/2);
577 297 up20180642
        text_set_halign(t_buffer, text_halign_left);
578
        text_set_valign(t_buffer, text_valign_center);
579
        text_set_color (t_buffer, TEXT_COLOR);
580
    }
581 298 up20180642
    text_t      *t_size   = NULL; {
582
        t_size = text_ctor(consolas, "");
583
        text_set_pos(t_size, rectangle_get_x(r_buffer)+rectangle_get_w(r_buffer)-5,
584 305 up20180642
        rectangle_get_y(r_buffer)+rectangle_get_h(r_buffer)-5);
585 298 up20180642
        text_set_halign(t_size, text_halign_right);
586
        text_set_valign(t_size, text_valign_bottom);
587
        text_set_color (t_size, TEXT_COLOR);
588
        text_set_size  (t_size, 18);
589
        char buffer2[20];
590
        sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
591
        text_set_text(t_size, buffer2);
592
    }
593 297 up20180642
594
    /** r_text */ {
595 305 up20180642
    r_text = rectangle_ctor(0,0,900,550);
596
    rectangle_set_pos(r_text, graph_get_XRes()/2  -rectangle_get_w(r_buffer)/2,
597
    graph_get_YRes()*0.09);
598
    rectangle_set_fill_color   (r_text, GRAPH_BLACK);
599
    rectangle_set_outline_width(r_text, 2);
600
    rectangle_set_outline_color(r_text, GRAPH_WHITE);
601
    rectangle_set_fill_trans(r_text, GRAPH_TRANSPARENT);
602
}
603
/** t_text */ {
604
for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
605
    t_text[i] = text_ctor(consolas, " ");
606
    text_set_pos(t_text[i], rectangle_get_x(r_text)+50,
607
    rectangle_get_y(r_text)+rectangle_get_h(r_text)-30-25*i);
608
    text_set_halign(t_text[i], text_halign_left);
609
    text_set_valign(t_text[i], text_valign_bottom);
610
    text_set_color (t_text[i], TEXT_COLOR);
611
}
612
}
613 297 up20180642
614 305 up20180642
/// loop stuff
615
uint32_t int_vector = 0;
616
int good = true;
617
while (good) {
618
    /* Get a request message. */
619
    if((r = get_interrupts_vector(&int_vector))) return r;
620
    for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
621
        if (int_vector & n) {
622
            interrupt_handler(i);
623
            switch (i) {
624 304 up20180642
                case TIMER0_IRQ:
625 305 up20180642
                graph_clear_screen();
626
                sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
627 297 up20180642
628 305 up20180642
                rectangle_draw(r_buffer);
629
                text_draw(t_buffer);
630
                text_draw(t_size);
631 297 up20180642
632 305 up20180642
                rectangle_draw(r_text);
633
                for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_draw(t_text[i]);
634 297 up20180642
635 305 up20180642
                sprite_draw(sp_crosshair);
636
                graph_draw();
637
                break;
638 304 up20180642
                case KBC_IRQ:
639 305 up20180642
                if      (scancode[0] == ESC_BREAK_CODE) good = false;
640
                else if (scancode[0] == ENTER_MAKE_CODE) {
641
                    hltp_send_string(buffer);
642
                    char buffer2[CHAT_MAX_SIZE+3] = "> ";
643
                    strncat(buffer2, buffer, strlen(buffer));
644
                    for(size_t i = CHAT_MAX_NUM-1; i; --i)
645
                    text_set_text(t_text[i], text_get_string(t_text[i-1]));
646
                    text_set_text(t_text[0], buffer2);
647
                    for(size_t i = 0; i < CHAT_MAX_NUM; ++i){
648
                        if(text_get_string(t_text[i])[0] == '>'){
649
                            text_set_pos(t_text[i], rectangle_get_x(r_text)+50, text_get_y(t_text[i]));
650
                            text_set_halign(t_text[i], text_halign_left);
651
                        }else{
652
                            text_set_pos(t_text[i], rectangle_get_x(r_text)+rectangle_get_w(r_text)-50, text_get_y(t_text[i]));
653
                            text_set_halign(t_text[i], text_halign_right);
654 297 up20180642
                        }
655
                    }
656 305 up20180642
                    buffer[0] = '\0';
657
                } else if(scancode[0] == BACKSPACE_MAKE_CODE){
658
                    buffer[strlen(buffer)-1] = '\0';
659
                } else {
660
                    char c = map_makecode(scancode[0]);
661
                    if (c == ERROR_CODE) break;
662
                    if(strlen(buffer) < CHAT_MAX_SIZE) strncat(buffer, &c, 1);
663
                    else                               printf("Char limit exceeded\n");
664
                }
665
                text_set_text(t_buffer, buffer);
666
                char buffer2[20];
667
                sprintf(buffer2, "%d/%d", strlen(buffer), CHAT_MAX_SIZE);
668
                text_set_text(t_size, buffer2);
669 304 up20180642
                case MOUSE_IRQ:
670 305 up20180642
                if (counter_mouse_ih >= 3) {
671
                    mouse_parse_packet(packet_mouse_ih, &pp);
672
                    update_mouse(&pp);
673
                    counter_mouse_ih = 0;
674
                }
675
                break;
676 304 up20180642
                case COM1_IRQ: nctp_ih(); break;
677 297 up20180642
            }
678
        }
679
    }
680 305 up20180642
}
681 297 up20180642
682 305 up20180642
rectangle_dtor(r_buffer);
683
text_dtor     (t_buffer);
684 297 up20180642
685 305 up20180642
rectangle_dtor(r_text);
686
for(size_t i = 0; i < CHAT_MAX_NUM; ++i) text_dtor(t_text[i]);
687 297 up20180642
688 305 up20180642
nctp_set_processor(NULL);
689 298 up20180642
690 305 up20180642
return SUCCESS;
691 296 up20180642
}