Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 132

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