Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 128

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