Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 265

History | View | Annotate | Download (19.8 KB)

1 93 up20180655
#include <lcom/lcf.h>
2
3
#include <lcom/lab5.h>
4
5
#include <stdint.h>
6
#include <stdio.h>
7
8 124 up20180642
#include "sprite.h"
9 94 up20180655
#include "graphics.h"
10
#include "graphics_macros.h"
11 109 up20180655
#include "keyboard.h"
12
#include "kbc.h"
13
#include "kbc_macros.h"
14 127 up20180642
#include "timer.h"
15 134 up20180642
#include "utils.h"
16 94 up20180655
17 93 up20180655
// Any header files included below this line should have been created by you
18
19
int main(int argc, char *argv[]) {
20 102 up20180642
    // sets the language of LCF messages (can be either EN-US or PT-PT)
21
    lcf_set_language("EN-US");
22 93 up20180655
23 102 up20180642
    // 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 93 up20180655
27 102 up20180642
    // 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 93 up20180655
31 102 up20180642
    // handles control over to LCF
32
    // [LCF handles command line arguments and invokes the right function]
33
    if (lcf_start(argc, argv))
34 93 up20180655
    return 1;
35
36 102 up20180642
    // LCF clean up tasks
37
    // [must be the last statement before return]
38
    lcf_cleanup();
39 93 up20180655
40 102 up20180642
    return 0;
41 93 up20180655
}
42
43
int(video_test_init)(uint16_t mode, uint8_t delay) {
44
45 103 up20180655
    if (vbe_get_mode_information(mode)) {
46 99 up20180655
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
47
        if (vg_exit())
48 103 up20180655
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
49 99 up20180655
        return 1;
50
    }
51
52 103 up20180655
    map_vram(); // if function fails it aborts program
53 99 up20180655
54 109 up20180655
    if (set_graphics_mode(mode)) {
55
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
56 138 up20180655
        if (vg_exit()) {
57 109 up20180655
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
58 138 up20180655
        }
59
        if (free_memory_map()) {
60
            printf("%s: lm_free failed\n", __func__);
61
        }
62 109 up20180655
        return 1;
63
    };
64
65 96 up20180655
    tickdelay(micros_to_ticks(delay*1e6));
66 94 up20180655
67 99 up20180655
    if (vg_exit()) {
68
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
69 133 up20180655
        if (free_memory_map())
70 103 up20180655
            printf("%s: lm_free failed\n", __func__);
71 99 up20180655
        return 1;
72
    }
73 102 up20180642
74 133 up20180655
    if (free_memory_map()) {
75 99 up20180655
        printf("%s: lm_free failed\n", __func__);
76
        return 1;
77 102 up20180642
    }
78 94 up20180655
    return 0;
79 93 up20180655
}
80
81 111 up20180642
// lcom_run lab5 "rectangle 105 100 100 100 100 1"
82
// lcom_run lab5 "rectangle 115 100 100 100 100 FF0000"
83 102 up20180642
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 93 up20180655
86 109 up20180655
    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 102 up20180642
    if (set_graphics_mode(mode)) {
96
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
97 138 up20180655
        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 102 up20180642
        return 1;
104
    };
105
106 138 up20180655
    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 109 up20180655
        }
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 138 up20180655
        if (free_memory_map()) {
133
            printf("%s: lm_free failed\n", __func__);
134
        }
135 109 up20180655
        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 138 up20180655
        if (free_memory_map()) {
166
            printf("%s: lm_free failed\n", __func__);
167
        }
168 109 up20180655
        return 1;
169
    };
170
171 102 up20180642
    if (vg_exit()) {
172
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
173 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
174 102 up20180642
        return 1;
175
    }
176 109 up20180655
177 133 up20180655
    if (free_memory_map()) {
178 109 up20180655
        printf("%s: lm_free failed\n", __func__);
179
        return 1;
180
    }
181
182 102 up20180642
    return 0;
183 93 up20180655
}
184
185
int(video_test_pattern)(uint16_t mode, uint8_t no_rectangles, uint32_t first, uint8_t step) {
186 111 up20180642
    int r;
187 103 up20180655
188 111 up20180642
    if (vbe_get_mode_information(mode)) {
189
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
190 116 up20180642
        if (vg_exit())
191
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
192 111 up20180642
        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 138 up20180655
        if (free_memory_map()) {
201
            printf("%s: lm_free failed\n", __func__);
202
        }
203 111 up20180642
        return 1;
204 116 up20180642
    };
205 112 up20180642
206 111 up20180642
    uint16_t W = get_XRes()/no_rectangles;
207
    uint16_t H = get_YRes()/no_rectangles;
208 116 up20180642
209 111 up20180642
    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 112 up20180642
            if(get_bytes_pixel() == 1){
213 111 up20180642
                color = (first + (row * no_rectangles + col) * step) % (1 << get_bits_pixel());
214
            }else{
215 113 up20180642
                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 111 up20180642
            }
220 138 up20180655
            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 111 up20180642
                }
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 138 up20180655
        if (free_memory_map()) {
250
            printf("%s: lm_free failed\n", __func__);
251
        }
252 111 up20180642
        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 138 up20180655
        if (free_memory_map()) {
283
            printf("%s: lm_free failed\n", __func__);
284
        }
285 111 up20180642
        return 1;
286
    };
287
288
    if (vg_exit()) {
289
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
290 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
291 111 up20180642
        return 1;
292
    }
293
294 133 up20180655
    if (free_memory_map()) {
295 111 up20180642
        printf("%s: lm_free failed\n", __func__);
296
        return 1;
297
    }
298
299
    return 0;
300 93 up20180655
}
301
302
int(video_test_xpm)(xpm_map_t xpm, uint16_t x, uint16_t y) {
303 122 up20180655
    int r;
304 93 up20180655
305 122 up20180655
    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 138 up20180655
        if (free_memory_map()) {
318
            printf("%s: lm_free failed\n", __func__);
319
        }
320 122 up20180655
        return 1;
321
    };
322
323 124 up20180642
    sprite_t *sp = sprite_ctor(xpm);
324
    sprite_set_pos(sp, x, y);
325
    sprite_draw(sp);
326 122 up20180655
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 138 up20180655
        if (free_memory_map()) {
339
            printf("%s: lm_free failed\n", __func__);
340
        }
341 122 up20180655
        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 138 up20180655
        if (free_memory_map()) {
372
            printf("%s: lm_free failed\n", __func__);
373
        }
374 122 up20180655
        return 1;
375
    };
376
377
    if (vg_exit()) {
378
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
379 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
380 122 up20180655
        return 1;
381
    }
382
383 133 up20180655
    if (free_memory_map()) {
384 122 up20180655
        printf("%s: lm_free failed\n", __func__);
385
        return 1;
386
    }
387
388
    return 0;
389 93 up20180655
}
390
391 102 up20180642
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 127 up20180642
    int r;
393 93 up20180655
394 127 up20180642
    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 138 up20180655
        if (free_memory_map()) {
407
            printf("%s: lm_free failed\n", __func__);
408
        }
409 127 up20180642
        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 138 up20180655
    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 127 up20180642
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 138 up20180655
        if (free_memory_map()) {
437
            printf("%s: lm_free failed\n", __func__);
438
        }
439 127 up20180642
        return 1;
440
    }
441
    ///
442 137 up20180642
    int16_t v = (speed <= 0 ? 1 : speed);
443
    int16_t vx = 0, vy = 0;
444 141 up20180642
    if(xi != xf) vx = (xi < xf ? v : -v);
445
    else         vy = (yi < yf ? v : -v);
446 137 up20180642
447 127 up20180642
    uint16_t Nt     = (speed <  0 ? -speed : 1);
448 136 up20180642
    uint32_t ticks_per_frame = frequency/(uint32_t)fr_rate;
449 127 up20180642
450
    /// loop stuff
451
    int ipc_status;
452
    message msg;
453
    /// cycle
454
    uint16_t x = xi, y = yi;
455 141 up20180642
456 140 up20180642
    sprite_set_pos(sp,x,y);
457
    clear_screen();
458 141 up20180642
    sprite_draw(sp);
459
460 127 up20180642
    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 140 up20180642
                        timer_int_handler();
472
                        if(no_interrupts == Nt*ticks_per_frame){
473
474 143 up20180655
                            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 140 up20180642
480 143 up20180655
                                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 140 up20180642
                            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 141 up20180642
                            sprite_draw(sp);
517 140 up20180642
518
                            no_interrupts = 0;
519 134 up20180642
                        }
520 127 up20180642
                    }
521 139 up20180642
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
522
                        kbc_ih();
523
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
524
                    }
525 127 up20180642
                    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 138 up20180655
        if (free_memory_map()) {
539
            printf("%s: lm_free failed\n", __func__);
540
        }
541 127 up20180642
        return 1;
542
    };
543
544 138 up20180655
    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 137 up20180642
554 127 up20180642
    if (vg_exit()) {
555
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
556 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
557 127 up20180642
        return 1;
558
    }
559
560 133 up20180655
    if (free_memory_map()) {
561 127 up20180642
        printf("%s: lm_free failed\n", __func__);
562
        return 1;
563
    }
564
565
    return 0;
566 93 up20180655
}
567
568
int(video_test_controller)() {
569
570 128 up20180655
    vg_vbe_contr_info_t cntrl_info;
571 122 up20180655
572 138 up20180655
    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 123 up20180642
577 138 up20180655
    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 128 up20180655
582
    return 0;
583 93 up20180655
}