Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 366

History | View | Annotate | Download (19.8 KB)

1
#include <lcom/lcf.h>
2

    
3
#include <lcom/lab5.h>
4

    
5
#include <stdint.h>
6
#include <stdio.h>
7

    
8
#include "sprite.h"
9
#include "graphics.h"
10
#include "graphics_macros.h"
11
#include "keyboard.h"
12
#include "kbc.h"
13
#include "kbc_macros.h"
14
#include "timer.h"
15
#include "utils.h"
16

    
17
// Any header files included below this line should have been created by you
18

    
19
int main(int argc, char *argv[]) {
20
    // sets the language of LCF messages (can be either EN-US or PT-PT)
21
    lcf_set_language("EN-US");
22

    
23
    // enables to log function invocations that are being "wrapped" by LCF
24
    // [comment this out if you don't want/need it]
25
    lcf_trace_calls("/home/lcom/labs/lab5/trace.txt");
26

    
27
    // enables to save the output of printf function calls on a file
28
    // [comment this out if you don't want/need it]
29
    lcf_log_output("/home/lcom/labs/lab5/output.txt");
30

    
31
    // handles control over to LCF
32
    // [LCF handles command line arguments and invokes the right function]
33
    if (lcf_start(argc, argv))
34
    return 1;
35

    
36
    // LCF clean up tasks
37
    // [must be the last statement before return]
38
    lcf_cleanup();
39

    
40
    return 0;
41
}
42

    
43
int(video_test_init)(uint16_t mode, uint8_t delay) {
44

    
45
    if (vbe_get_mode_information(mode)) {
46
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
47
        if (vg_exit())
48
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
49
        return 1;
50
    }
51

    
52
    map_vram(); // if function fails it aborts program
53

    
54
    if (set_graphics_mode(mode)) {
55
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
56
        if (vg_exit()) {
57
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
58
        }
59
        if (free_memory_map()) {
60
            printf("%s: lm_free failed\n", __func__);
61
        }
62
        return 1;
63
    };
64

    
65
    tickdelay(micros_to_ticks(delay*1e6));
66

    
67
    if (vg_exit()) {
68
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
69
        if (free_memory_map())
70
            printf("%s: lm_free failed\n", __func__);
71
        return 1;
72
    }
73

    
74
    if (free_memory_map()) {
75
        printf("%s: lm_free failed\n", __func__);
76
        return 1;
77
    }
78
    return 0;
79
}
80

    
81
// lcom_run lab5 "rectangle 105 100 100 100 100 1"
82
// lcom_run lab5 "rectangle 115 100 100 100 100 FF0000"
83
int(video_test_rectangle)(uint16_t mode, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) {
84
    int r;
85

    
86
    if (vbe_get_mode_information(mode)) {
87
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
88
        if (vg_exit())
89
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
90
        return 1;
91
    }
92

    
93
    map_vram(); // if function fails it aborts program
94

    
95
    if (set_graphics_mode(mode)) {
96
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
97
        if (vg_exit()) {
98
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
99
        }
100
        if (free_memory_map()) {
101
            printf("%s: lm_free failed\n", __func__);
102
        }
103
        return 1;
104
    };
105

    
106
    uint16_t w = (x + width > get_XRes()) ? (get_XRes() - x) : (width);
107
    uint16_t h = (y + height > get_YRes()) ? (get_YRes() - y) : (height);
108

    
109
    if (x < get_XRes() && y < get_YRes()) {
110
        if (vg_draw_rectangle(x, y, w, h, color)) {
111
            if (vg_exit()) {
112
                printf("%s: vg_exit failed to exit to text mode.\n", __func__);
113
            }
114
            if (free_memory_map()) {
115
                printf("%s: lm_free failed\n", __func__);
116
            }
117
            return 1;
118
        }
119
    }
120

    
121
    /// loop stuff
122
    int ipc_status;
123
    message msg;
124
    /// Keyboard interrupt handling
125
    uint8_t kbc_irq_bit = KBC_IRQ;
126
    int kbc_id = 0;
127
    int kbc_irq = BIT(kbc_irq_bit);
128
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
129
        if (vg_exit()) {
130
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
131
        }
132
        if (free_memory_map()) {
133
            printf("%s: lm_free failed\n", __func__);
134
        }
135
        return 1;
136
    }
137
    /// cycle
138
    int good = 1;
139
    while (good) {
140
        /* Get a request message. */
141
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
142
            printf("driver_receive failed with %d", r);
143
            continue;
144
        }
145
        if (is_ipc_notify(ipc_status)) { /* received notification */
146
            switch (_ENDPOINT_P(msg.m_source)) {
147
                case HARDWARE: /* hardware interrupt notification */
148
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
149
                        kbc_ih();
150
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
151
                    }
152
                    break;
153
                default:
154
                    break; /* no other notifications expected: do nothing */
155
            }
156
        } else { /* received standart message, not a notification */
157
            /* no standart message expected: do nothing */
158
        }
159
    }
160

    
161
    if (unsubscribe_interrupt(&kbc_id)) {
162
        if (vg_exit()) {
163
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
164
        }
165
        if (free_memory_map()) {
166
            printf("%s: lm_free failed\n", __func__);
167
        }
168
        return 1;
169
    };
170

    
171
    if (vg_exit()) {
172
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
173
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
174
        return 1;
175
    }
176

    
177
    if (free_memory_map()) {
178
        printf("%s: lm_free failed\n", __func__);
179
        return 1;
180
    }
181

    
182
    return 0;
183
}
184

    
185
int(video_test_pattern)(uint16_t mode, uint8_t no_rectangles, uint32_t first, uint8_t step) {
186
    int r;
187

    
188
    if (vbe_get_mode_information(mode)) {
189
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
190
        if (vg_exit())
191
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
192
        return 1;
193
    }
194

    
195
    map_vram(); // if function fails it aborts program
196

    
197
    if (set_graphics_mode(mode)) {
198
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
199
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
200
        if (free_memory_map()) {
201
            printf("%s: lm_free failed\n", __func__);
202
        }
203
        return 1;
204
    };
205

    
206
    uint16_t W = get_XRes()/no_rectangles;
207
    uint16_t H = get_YRes()/no_rectangles;
208

    
209
    uint32_t color, R, G, B;
210
    for(uint8_t row = 0; row < no_rectangles; ++row){
211
        for(uint8_t col = 0; col < no_rectangles; ++col){
212
            if(get_bytes_pixel() == 1){
213
                color = (first + (row * no_rectangles + col) * step) % (1 << get_bits_pixel());
214
            }else{
215
                R = (GET_RED(first) + col*step) % (1 << get_RedMaskSize());
216
                G = (GET_GRE(first) + row*step) % (1 << get_GreenMaskSize());
217
                B = (GET_BLU(first) + (col+row)*step) % (1 << get_BlueMaskSize());
218
                color = SET_COLOR(R,G,B);
219
            }
220
            uint16_t x = col * W;
221
            uint16_t y = row * H;
222
            uint16_t w = (x + W > get_XRes()) ? (get_XRes() - x) : (W);
223
            uint16_t h = (y + H > get_YRes()) ? (get_YRes() - y) : (H);
224

    
225
            if (x < get_XRes() && y < get_YRes()) {
226
                if (vg_draw_rectangle(x,y,w,h,color)) {
227
                    if (vg_exit()) {
228
                        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
229
                    }
230
                    if (free_memory_map()) {
231
                        printf("%s: lm_free failed\n", __func__);
232
                    }
233
                    return 1;
234
                }
235
            }
236
        }
237
    }
238
    /// loop stuff
239
    int ipc_status;
240
    message msg;
241
    /// Keyboard interrupt handling
242
    uint8_t kbc_irq_bit = KBC_IRQ;
243
    int kbc_id = 0;
244
    int kbc_irq = BIT(kbc_irq_bit);
245
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
246
        if (vg_exit()) {
247
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
248
        }
249
        if (free_memory_map()) {
250
            printf("%s: lm_free failed\n", __func__);
251
        }
252
        return 1;
253
    }
254
    /// cycle
255
    int good = 1;
256
    while (good) {
257
        /* Get a request message. */
258
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
259
            printf("driver_receive failed with %d", r);
260
            continue;
261
        }
262
        if (is_ipc_notify(ipc_status)) { /* received notification */
263
            switch (_ENDPOINT_P(msg.m_source)) {
264
                case HARDWARE: /* hardware interrupt notification */
265
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
266
                        kbc_ih();
267
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
268
                    }
269
                    break;
270
                default:
271
                    break; /* no other notifications expected: do nothing */
272
            }
273
        } else { /* received standart message, not a notification */
274
            /* no standart message expected: do nothing */
275
        }
276
    }
277

    
278
    if (unsubscribe_interrupt(&kbc_id)) {
279
        if (vg_exit()) {
280
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
281
        }
282
        if (free_memory_map()) {
283
            printf("%s: lm_free failed\n", __func__);
284
        }
285
        return 1;
286
    };
287

    
288
    if (vg_exit()) {
289
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
290
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
291
        return 1;
292
    }
293

    
294
    if (free_memory_map()) {
295
        printf("%s: lm_free failed\n", __func__);
296
        return 1;
297
    }
298

    
299
    return 0;
300
}
301

    
302
int(video_test_xpm)(xpm_map_t xpm, uint16_t x, uint16_t y) {
303
    int r;
304

    
305
    if (vbe_get_mode_information(INDEXED_1024_768)) {
306
        printf("%s: failed to get information for mode %x.\n", __func__, INDEXED_1024_768);
307
        if (vg_exit())
308
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
309
        return 1;
310
    }
311

    
312
    map_vram(); // if function fails it aborts program
313

    
314
    if (set_graphics_mode(INDEXED_1024_768)) {
315
        printf("%s: failed to set graphic mode %x.\n", __func__, INDEXED_1024_768);
316
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
317
        if (free_memory_map()) {
318
            printf("%s: lm_free failed\n", __func__);
319
        }
320
        return 1;
321
    };
322

    
323
    sprite_t *sp = sprite_ctor(xpm);
324
    sprite_set_pos(sp, x, y);
325
    sprite_draw(sp);
326

    
327
    /// loop stuff
328
    int ipc_status;
329
    message msg;
330
    /// Keyboard interrupt handling
331
    uint8_t kbc_irq_bit = KBC_IRQ;
332
    int kbc_id = 0;
333
    int kbc_irq = BIT(kbc_irq_bit);
334
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
335
        if (vg_exit()) {
336
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
337
        }
338
        if (free_memory_map()) {
339
            printf("%s: lm_free failed\n", __func__);
340
        }
341
        return 1;
342
    }
343
    /// cycle
344
    int good = 1;
345
    while (good) {
346
        /* Get a request message. */
347
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
348
            printf("driver_receive failed with %d", r);
349
            continue;
350
        }
351
        if (is_ipc_notify(ipc_status)) { /* received notification */
352
            switch (_ENDPOINT_P(msg.m_source)) {
353
                case HARDWARE: /* hardware interrupt notification */
354
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
355
                        kbc_ih();
356
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
357
                    }
358
                    break;
359
                default:
360
                    break; /* no other notifications expected: do nothing */
361
            }
362
        } else { /* received standart message, not a notification */
363
            /* no standart message expected: do nothing */
364
        }
365
    }
366

    
367
    if (unsubscribe_interrupt(&kbc_id)) {
368
        if (vg_exit()) {
369
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
370
        }
371
        if (free_memory_map()) {
372
            printf("%s: lm_free failed\n", __func__);
373
        }
374
        return 1;
375
    };
376

    
377
    if (vg_exit()) {
378
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
379
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
380
        return 1;
381
    }
382

    
383
    if (free_memory_map()) {
384
        printf("%s: lm_free failed\n", __func__);
385
        return 1;
386
    }
387

    
388
    return 0;
389
}
390

    
391
int(video_test_move)(xpm_map_t xpm, uint16_t xi, uint16_t yi, uint16_t xf, uint16_t yf, int16_t speed, uint8_t fr_rate) {
392
    int r;
393

    
394
    if (vbe_get_mode_information(INDEXED_1024_768)) {
395
        printf("%s: failed to get information for mode %x.\n", __func__, INDEXED_1024_768);
396
        if (vg_exit())
397
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
398
        return 1;
399
    }
400

    
401
    map_vram(); // if function fails it aborts program
402

    
403
    if (set_graphics_mode(INDEXED_1024_768)) {
404
        printf("%s: failed to set graphic mode %x.\n", __func__, INDEXED_1024_768);
405
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
406
        if (free_memory_map()) {
407
            printf("%s: lm_free failed\n", __func__);
408
        }
409
        return 1;
410
    };
411

    
412
    sprite_t *sp = sprite_ctor(xpm);
413

    
414
    /// Timer interrupt handling
415
    const uint32_t frequency = sys_hz(); // Frequency asummed at 60Hz
416
    uint8_t timer_irq_bit = 0;
417
    int timer_id = 0;
418
    int timer_irq = BIT(timer_irq_bit);
419
    if(subscribe_timer_interrupt(timer_irq_bit, &timer_id)) {
420
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
421
        if (free_memory_map()) {
422
            printf("%s: lm_free failed\n", __func__);
423
        }
424
        return 1;
425
    }
426

    
427
    no_interrupts = 0;
428
    /// Keyboard interrupt handling
429
    uint8_t kbc_irq_bit = KBC_IRQ;
430
    int kbc_id = 0;
431
    int kbc_irq = BIT(kbc_irq_bit);
432
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
433
        if (vg_exit()) {
434
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
435
        }
436
        if (free_memory_map()) {
437
            printf("%s: lm_free failed\n", __func__);
438
        }
439
        return 1;
440
    }
441
    ///
442
    int16_t v = (speed <= 0 ? 1 : speed);
443
    int16_t vx = 0, vy = 0;
444
    if(xi != xf) vx = (xi < xf ? v : -v);
445
    else         vy = (yi < yf ? v : -v);
446

    
447
    uint16_t Nt     = (speed <  0 ? -speed : 1);
448
    uint32_t ticks_per_frame = frequency/(uint32_t)fr_rate;
449

    
450
    /// loop stuff
451
    int ipc_status;
452
    message msg;
453
    /// cycle
454
    uint16_t x = xi, y = yi;
455

    
456
    sprite_set_pos(sp,x,y);
457
    clear_screen();
458
    sprite_draw(sp);
459

    
460
    int good = 1;
461
    while (good) {
462
        /* Get a request message. */
463
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
464
            printf("driver_receive failed with %d", r);
465
            continue;
466
        }
467
        if (is_ipc_notify(ipc_status)) { /* received notification */
468
            switch (_ENDPOINT_P(msg.m_source)) {
469
                case HARDWARE: /* hardware interrupt notification */
470
                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
471
                        timer_int_handler();
472
                        if(no_interrupts == Nt*ticks_per_frame){
473

    
474
                            if(vx) {
475
                                uint16_t x_clear = (vx > 0 ? x : x+sprite_get_w(sp)+vx);
476
                                uint16_t y_clear = y;
477
                                uint16_t w = (x + abs(v) > get_XRes()) ? (get_XRes() - x) : (abs(v));
478
                                uint16_t h = (y + sprite_get_h(sp) > get_YRes()) ? (get_YRes() - y) : (sprite_get_h(sp));
479

    
480
                                if (x_clear < get_XRes() && y_clear < get_YRes()) {
481
                                    if (draw_rectangle(x_clear,y_clear,w,h, BLACK)) {
482
                                        if (vg_exit()) {
483
                                            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
484
                                        }
485
                                        if (free_memory_map()) {
486
                                            printf("%s: lm_free failed\n", __func__);
487
                                        }
488
                                        return 1;
489
                                    }
490
                                }
491
                            }
492
                            if(vy) {
493
                                uint16_t x_clear = x;
494
                                uint16_t y_clear = (vy > 0 ? y : y+sprite_get_h(sp)+vy);
495
                                uint16_t w = (x + sprite_get_w(sp) > get_XRes()) ? (get_XRes() - x) : (sprite_get_w(sp));
496
                                uint16_t h = (y + abs(v) > get_YRes()) ? (get_YRes() - y) : (abs(v));
497

    
498
                                if (x_clear < get_XRes() && y_clear < get_YRes()) {
499
                                    if (draw_rectangle(x_clear,y_clear,w,h, BLACK)) {
500
                                        if (vg_exit()) {
501
                                            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
502
                                        }
503
                                        if (free_memory_map()) {
504
                                            printf("%s: lm_free failed\n", __func__);
505
                                        }
506
                                        return 1;
507
                                    }
508
                                }
509
                            }
510

    
511
                            vx = (vx > 0 ? min(vx, xf-x) : max(vx, xf-x) );
512
                            vy = (vy > 0 ? min(vy, yf-y) : max(vy, yf-y) );
513
                            x += vx;
514
                            y += vy;
515
                            sprite_set_pos(sp,x,y);
516
                            sprite_draw(sp);
517

    
518
                            no_interrupts = 0;
519
                        }
520
                    }
521
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
522
                        kbc_ih();
523
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
524
                    }
525
                    break;
526
                default:
527
                    break; /* no other notifications expected: do nothing */
528
            }
529
        } else { /* received standart message, not a notification */
530
            /* no standart message expected: do nothing */
531
        }
532
    }
533

    
534
    if (unsubscribe_interrupt(&kbc_id)) {
535
        if (vg_exit()) {
536
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
537
        }
538
        if (free_memory_map()) {
539
            printf("%s: lm_free failed\n", __func__);
540
        }
541
        return 1;
542
    };
543

    
544
    if (unsubscribe_interrupt(&timer_id)) {
545
        if (vg_exit()) {
546
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
547
        }
548
        if (free_memory_map()) {
549
            printf("%s: lm_free failed\n", __func__);
550
        }
551
        return 1;
552
    }
553

    
554
    if (vg_exit()) {
555
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
556
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
557
        return 1;
558
    }
559

    
560
    if (free_memory_map()) {
561
        printf("%s: lm_free failed\n", __func__);
562
        return 1;
563
    }
564

    
565
    return 0;
566
}
567

    
568
int(video_test_controller)() {
569

    
570
    vg_vbe_contr_info_t cntrl_info;
571

    
572
    if (vbe_get_controller_information(&cntrl_info)) {
573
        printf("%s: vbe_get_controller_information failed to get controller info.\n", __func__);
574
        return 1;
575
    }
576

    
577
    if (vg_display_vbe_contr_info(&cntrl_info)) {
578
        printf("%s: vg_display_vbe_contr_info failed to display controller info.\n", __func__);
579
        return 1;
580
    }
581

    
582
    return 0;
583
}