Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 135

History | View | Annotate | Download (16 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
        if (vg_exit())
57
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
58
        return 1;
59
    };
60
61 96 up20180655
    tickdelay(micros_to_ticks(delay*1e6));
62 94 up20180655
63 99 up20180655
    if (vg_exit()) {
64
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
65 133 up20180655
        if (free_memory_map())
66 103 up20180655
            printf("%s: lm_free failed\n", __func__);
67 99 up20180655
        return 1;
68
    }
69 102 up20180642
70 133 up20180655
    if (free_memory_map()) {
71 99 up20180655
        printf("%s: lm_free failed\n", __func__);
72
        return 1;
73 102 up20180642
    }
74 94 up20180655
    return 0;
75 93 up20180655
}
76
77 111 up20180642
// lcom_run lab5 "rectangle 105 100 100 100 100 1"
78
// lcom_run lab5 "rectangle 115 100 100 100 100 FF0000"
79 102 up20180642
int(video_test_rectangle)(uint16_t mode, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) {
80
    int r;
81 93 up20180655
82 109 up20180655
    if (vbe_get_mode_information(mode)) {
83
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
84
        if (vg_exit())
85
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
86
        return 1;
87
    }
88
89
    map_vram(); // if function fails it aborts program
90
91 102 up20180642
    if (set_graphics_mode(mode)) {
92
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
93
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
94
        return 1;
95
    };
96
97 132 up20180655
    if (vg_draw_rectangle(x, y, width, height, color)) {
98 109 up20180655
        if (vg_exit()) {
99
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
100 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
101 109 up20180655
        }
102
        return 1;
103
    }
104
105
    /// loop stuff
106
    int ipc_status;
107
    message msg;
108
    /// Keyboard interrupt handling
109
    uint8_t kbc_irq_bit = KBC_IRQ;
110
    int kbc_id = 0;
111
    int kbc_irq = BIT(kbc_irq_bit);
112
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
113
        if (vg_exit()) {
114
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
115 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
116 109 up20180655
        }
117
        return 1;
118
    }
119
    /// cycle
120
    int good = 1;
121
    while (good) {
122
        /* Get a request message. */
123
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
124
            printf("driver_receive failed with %d", r);
125
            continue;
126
        }
127
        if (is_ipc_notify(ipc_status)) { /* received notification */
128
            switch (_ENDPOINT_P(msg.m_source)) {
129
                case HARDWARE: /* hardware interrupt notification */
130
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
131
                        kbc_ih();
132
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
133
                    }
134
                    break;
135
                default:
136
                    break; /* no other notifications expected: do nothing */
137
            }
138
        } else { /* received standart message, not a notification */
139
            /* no standart message expected: do nothing */
140
        }
141
    }
142
143
    if (unsubscribe_interrupt(&kbc_id)) {
144
        if (vg_exit()) {
145
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
146 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
147 109 up20180655
        }
148
        return 1;
149
    };
150
151 102 up20180642
    if (vg_exit()) {
152
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
153 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
154 102 up20180642
        return 1;
155
    }
156 109 up20180655
157 133 up20180655
    if (free_memory_map()) {
158 109 up20180655
        printf("%s: lm_free failed\n", __func__);
159
        return 1;
160
    }
161
162 102 up20180642
    return 0;
163 93 up20180655
}
164
165
int(video_test_pattern)(uint16_t mode, uint8_t no_rectangles, uint32_t first, uint8_t step) {
166 111 up20180642
    int r;
167 103 up20180655
168 111 up20180642
    if (vbe_get_mode_information(mode)) {
169
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
170 116 up20180642
        if (vg_exit())
171
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
172 111 up20180642
        return 1;
173
    }
174
175
    map_vram(); // if function fails it aborts program
176
177
    if (set_graphics_mode(mode)) {
178
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
179
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
180
        return 1;
181 116 up20180642
    };
182 112 up20180642
183 111 up20180642
    uint16_t W = get_XRes()/no_rectangles;
184
    uint16_t H = get_YRes()/no_rectangles;
185 116 up20180642
186 111 up20180642
    uint32_t color, R, G, B;
187
    for(uint8_t row = 0; row < no_rectangles; ++row){
188
        for(uint8_t col = 0; col < no_rectangles; ++col){
189 112 up20180642
            if(get_bytes_pixel() == 1){
190 111 up20180642
                color = (first + (row * no_rectangles + col) * step) % (1 << get_bits_pixel());
191
            }else{
192 113 up20180642
                R = (GET_RED(first) + col*step) % (1 << get_RedMaskSize());
193
                G = (GET_GRE(first) + row*step) % (1 << get_GreenMaskSize());
194
                B = (GET_BLU(first) + (col+row)*step) % (1 << get_BlueMaskSize());
195
                color = SET_COLOR(R,G,B);
196 111 up20180642
            }
197 132 up20180655
            if (vg_draw_rectangle(col*W,row*H,W,H,color)) {
198 111 up20180642
                if (vg_exit()) {
199
                    printf("%s: vg_exit failed to exit to text mode.\n", __func__);
200 133 up20180655
                    if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
201 111 up20180642
                }
202
                return 1;
203
            }
204
        }
205
    }
206
    /// loop stuff
207
    int ipc_status;
208
    message msg;
209
    /// Keyboard interrupt handling
210
    uint8_t kbc_irq_bit = KBC_IRQ;
211
    int kbc_id = 0;
212
    int kbc_irq = BIT(kbc_irq_bit);
213
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
214
        if (vg_exit()) {
215
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
216 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
217 111 up20180642
        }
218
        return 1;
219
    }
220
    /// cycle
221
    int good = 1;
222
    while (good) {
223
        /* Get a request message. */
224
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
225
            printf("driver_receive failed with %d", r);
226
            continue;
227
        }
228
        if (is_ipc_notify(ipc_status)) { /* received notification */
229
            switch (_ENDPOINT_P(msg.m_source)) {
230
                case HARDWARE: /* hardware interrupt notification */
231
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
232
                        kbc_ih();
233
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
234
                    }
235
                    break;
236
                default:
237
                    break; /* no other notifications expected: do nothing */
238
            }
239
        } else { /* received standart message, not a notification */
240
            /* no standart message expected: do nothing */
241
        }
242
    }
243
244
    if (unsubscribe_interrupt(&kbc_id)) {
245
        if (vg_exit()) {
246
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
247 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
248 111 up20180642
        }
249
        return 1;
250
    };
251
252
    if (vg_exit()) {
253
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
254 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
255 111 up20180642
        return 1;
256
    }
257
258 133 up20180655
    if (free_memory_map()) {
259 111 up20180642
        printf("%s: lm_free failed\n", __func__);
260
        return 1;
261
    }
262
263
    return 0;
264 93 up20180655
}
265
266
int(video_test_xpm)(xpm_map_t xpm, uint16_t x, uint16_t y) {
267 122 up20180655
    int r;
268 93 up20180655
269 122 up20180655
    if (vbe_get_mode_information(INDEXED_1024_768)) {
270
        printf("%s: failed to get information for mode %x.\n", __func__, INDEXED_1024_768);
271
        if (vg_exit())
272
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
273
        return 1;
274
    }
275
276
    map_vram(); // if function fails it aborts program
277
278
    if (set_graphics_mode(INDEXED_1024_768)) {
279
        printf("%s: failed to set graphic mode %x.\n", __func__, INDEXED_1024_768);
280
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
281
        return 1;
282
    };
283
284 124 up20180642
    sprite_t *sp = sprite_ctor(xpm);
285
    sprite_set_pos(sp, x, y);
286
    sprite_draw(sp);
287 122 up20180655
288
    /// loop stuff
289
    int ipc_status;
290
    message msg;
291
    /// Keyboard interrupt handling
292
    uint8_t kbc_irq_bit = KBC_IRQ;
293
    int kbc_id = 0;
294
    int kbc_irq = BIT(kbc_irq_bit);
295
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
296
        if (vg_exit()) {
297
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
298 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
299 122 up20180655
        }
300
        return 1;
301
    }
302
    /// cycle
303
    int good = 1;
304
    while (good) {
305
        /* Get a request message. */
306
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
307
            printf("driver_receive failed with %d", r);
308
            continue;
309
        }
310
        if (is_ipc_notify(ipc_status)) { /* received notification */
311
            switch (_ENDPOINT_P(msg.m_source)) {
312
                case HARDWARE: /* hardware interrupt notification */
313
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
314
                        kbc_ih();
315
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
316
                    }
317
                    break;
318
                default:
319
                    break; /* no other notifications expected: do nothing */
320
            }
321
        } else { /* received standart message, not a notification */
322
            /* no standart message expected: do nothing */
323
        }
324
    }
325
326
    if (unsubscribe_interrupt(&kbc_id)) {
327
        if (vg_exit()) {
328
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
329 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
330 122 up20180655
        }
331
        return 1;
332
    };
333
334
    if (vg_exit()) {
335
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
336 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
337 122 up20180655
        return 1;
338
    }
339
340 133 up20180655
    if (free_memory_map()) {
341 122 up20180655
        printf("%s: lm_free failed\n", __func__);
342
        return 1;
343
    }
344
345
    return 0;
346 93 up20180655
}
347
348 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) {
349 127 up20180642
    int r;
350 93 up20180655
351 127 up20180642
    if (vbe_get_mode_information(INDEXED_1024_768)) {
352
        printf("%s: failed to get information for mode %x.\n", __func__, INDEXED_1024_768);
353
        if (vg_exit())
354
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
355
        return 1;
356
    }
357
358
    map_vram(); // if function fails it aborts program
359
360
    if (set_graphics_mode(INDEXED_1024_768)) {
361
        printf("%s: failed to set graphic mode %x.\n", __func__, INDEXED_1024_768);
362
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
363
        return 1;
364
    };
365
366
    sprite_t *sp = sprite_ctor(xpm);
367
368
    /// Timer interrupt handling
369
    const uint32_t frequency = sys_hz(); // Frequency asummed at 60Hz
370
    uint8_t timer_irq_bit = 0;
371
    int timer_id = 0;
372
    int timer_irq = BIT(timer_irq_bit);
373
    if(subscribe_timer_interrupt(timer_irq_bit, &timer_id)) return 1;
374
375
    no_interrupts = 0;
376
    /// Keyboard interrupt handling
377
    uint8_t kbc_irq_bit = KBC_IRQ;
378
    int kbc_id = 0;
379
    int kbc_irq = BIT(kbc_irq_bit);
380
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
381
        if (vg_exit()) {
382
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
383 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
384 127 up20180642
        }
385
        return 1;
386
    }
387
    ///
388
    uint16_t dx = xf-xi;
389
    uint16_t dy = yf-yi;
390
    if(xi != xf) dy = 0;
391
    else         dx = 0;
392
    uint16_t dframe = (speed <= 0 ? 1 : speed);
393
    uint16_t Nt     = (speed <  0 ? -speed : 1);
394
    uint32_t dt     = frequency/(uint32_t)fr_rate;
395
396
    /// loop stuff
397
    int ipc_status;
398
    message msg;
399
    /// cycle
400
    uint16_t x = xi, y = yi;
401
    int i = Nt-1;
402
    int good = 1;
403
    while (good) {
404
        /* Get a request message. */
405
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
406
            printf("driver_receive failed with %d", r);
407
            continue;
408
        }
409
        if (is_ipc_notify(ipc_status)) { /* received notification */
410
            switch (_ENDPOINT_P(msg.m_source)) {
411
                case HARDWARE: /* hardware interrupt notification */
412 135 up20180642
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
413
                        kbc_ih();
414
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
415
                    }
416 127 up20180642
                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
417 134 up20180642
                        if(no_interrupts == dt){
418
                            no_interrupts = 0;
419
                            i = (i+1)%Nt;
420 135 up20180642
                            if(i == 0){
421
                                sprite_set_pos(sp,x,y);
422
                                sprite_draw(sp);
423
                                static int cnt = 0;
424
                                cnt++; printf("printed %d times\n", cnt);
425 134 up20180642
                                if(dx) draw_rectangle(min(x,x+dframe),y              , abs(dframe)    , sprite_get_h(sp), 0);
426
                                if(dy) draw_rectangle(x              ,min(y,y+dframe),sprite_get_w(sp), abs(dframe)     , 0);
427
                                if(dx) x += dframe;
428
                                if(dy) y += dframe;
429 135 up20180642
                                if(dx && (x-xi)*(x-xf) >= 0){ x = xf; dx = 0; }
430
                                if(dy && (y-yi)*(y-yf) >= 0){ y = yf; dy = 0; }
431 134 up20180642
                            }
432
                        }
433 135 up20180642
                        timer_int_handler();
434 127 up20180642
                    }
435
                    break;
436
                default:
437
                    break; /* no other notifications expected: do nothing */
438
            }
439
        } else { /* received standart message, not a notification */
440
            /* no standart message expected: do nothing */
441
        }
442
        if(good == 0) continue;
443
    }
444
445
    if (unsubscribe_interrupt(&kbc_id)) {
446
        if (vg_exit()) {
447
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
448 133 up20180655
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
449 127 up20180642
        }
450
        return 1;
451
    };
452
453
    if (vg_exit()) {
454
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
455 133 up20180655
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
456 127 up20180642
        return 1;
457
    }
458
459 133 up20180655
    if (free_memory_map()) {
460 127 up20180642
        printf("%s: lm_free failed\n", __func__);
461
        return 1;
462
    }
463
464
    return 0;
465 93 up20180655
}
466
467
int(video_test_controller)() {
468
469 128 up20180655
    vg_vbe_contr_info_t cntrl_info;
470 122 up20180655
471 128 up20180655
    vbe_get_controller_information(&cntrl_info);
472 123 up20180642
473 128 up20180655
    vg_display_vbe_contr_info(&cntrl_info);
474
475
    return 0;
476 93 up20180655
}