Project

General

Profile

Statistics
| Revision:

root / lab5 / lab5.c @ 135

History | View | Annotate | Download (16 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
        return 1;
59
    };
60

    
61
    tickdelay(micros_to_ticks(delay*1e6));
62

    
63
    if (vg_exit()) {
64
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
65
        if (free_memory_map())
66
            printf("%s: lm_free failed\n", __func__);
67
        return 1;
68
    }
69

    
70
    if (free_memory_map()) {
71
        printf("%s: lm_free failed\n", __func__);
72
        return 1;
73
    }
74
    return 0;
75
}
76

    
77
// lcom_run lab5 "rectangle 105 100 100 100 100 1"
78
// lcom_run lab5 "rectangle 115 100 100 100 100 FF0000"
79
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

    
82
    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
    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
    if (vg_draw_rectangle(x, y, width, height, color)) {
98
        if (vg_exit()) {
99
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
100
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
101
        }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
116
        }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
147
        }
148
        return 1;
149
    };
150

    
151
    if (vg_exit()) {
152
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
153
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
154
        return 1;
155
    }
156

    
157
    if (free_memory_map()) {
158
        printf("%s: lm_free failed\n", __func__);
159
        return 1;
160
    }
161

    
162
    return 0;
163
}
164

    
165
int(video_test_pattern)(uint16_t mode, uint8_t no_rectangles, uint32_t first, uint8_t step) {
166
    int r;
167

    
168
    if (vbe_get_mode_information(mode)) {
169
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
170
        if (vg_exit())
171
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
172
        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
    };
182

    
183
    uint16_t W = get_XRes()/no_rectangles;
184
    uint16_t H = get_YRes()/no_rectangles;
185

    
186
    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
            if(get_bytes_pixel() == 1){
190
                color = (first + (row * no_rectangles + col) * step) % (1 << get_bits_pixel());
191
            }else{
192
                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
            }
197
            if (vg_draw_rectangle(col*W,row*H,W,H,color)) {
198
                if (vg_exit()) {
199
                    printf("%s: vg_exit failed to exit to text mode.\n", __func__);
200
                    if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
201
                }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
217
        }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
248
        }
249
        return 1;
250
    };
251

    
252
    if (vg_exit()) {
253
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
254
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
255
        return 1;
256
    }
257

    
258
    if (free_memory_map()) {
259
        printf("%s: lm_free failed\n", __func__);
260
        return 1;
261
    }
262

    
263
    return 0;
264
}
265

    
266
int(video_test_xpm)(xpm_map_t xpm, uint16_t x, uint16_t y) {
267
    int r;
268

    
269
    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
    sprite_t *sp = sprite_ctor(xpm);
285
    sprite_set_pos(sp, x, y);
286
    sprite_draw(sp);
287

    
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
299
        }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
330
        }
331
        return 1;
332
    };
333

    
334
    if (vg_exit()) {
335
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
336
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
337
        return 1;
338
    }
339

    
340
    if (free_memory_map()) {
341
        printf("%s: lm_free failed\n", __func__);
342
        return 1;
343
    }
344

    
345
    return 0;
346
}
347

    
348
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
    int r;
350

    
351
    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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
384
        }
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
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
413
                        kbc_ih();
414
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
415
                    }
416
                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
417
                        if(no_interrupts == dt){
418
                            no_interrupts = 0;
419
                            i = (i+1)%Nt;
420
                            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
                                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
                                if(dx && (x-xi)*(x-xf) >= 0){ x = xf; dx = 0; }
430
                                if(dy && (y-yi)*(y-yf) >= 0){ y = yf; dy = 0; }
431
                            }
432
                        }
433
                        timer_int_handler();
434
                    }
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
            if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
449
        }
450
        return 1;
451
    };
452

    
453
    if (vg_exit()) {
454
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
455
        if (free_memory_map()) printf("%s: lm_free failed\n", __func__);
456
        return 1;
457
    }
458

    
459
    if (free_memory_map()) {
460
        printf("%s: lm_free failed\n", __func__);
461
        return 1;
462
    }
463

    
464
    return 0;
465
}
466

    
467
int(video_test_controller)() {
468

    
469
    vg_vbe_contr_info_t cntrl_info;
470

    
471
    vbe_get_controller_information(&cntrl_info);
472

    
473
    vg_display_vbe_contr_info(&cntrl_info);
474

    
475
    return 0;
476
}