diff options
Diffstat (limited to 'uisimulator/common/lcd-playersim.c')
-rw-r--r-- | uisimulator/common/lcd-playersim.c | 264 |
1 files changed, 67 insertions, 197 deletions
diff --git a/uisimulator/common/lcd-playersim.c b/uisimulator/common/lcd-playersim.c index a2ff344345..a804cc4b7e 100644 --- a/uisimulator/common/lcd-playersim.c +++ b/uisimulator/common/lcd-playersim.c | |||
@@ -27,96 +27,80 @@ | |||
27 | #include "file.h" | 27 | #include "file.h" |
28 | #include "debug.h" | 28 | #include "debug.h" |
29 | #include "system.h" | 29 | #include "system.h" |
30 | #include "font.h" | 30 | |
31 | #include "font-player.h" | ||
31 | 32 | ||
32 | /*** definitions ***/ | 33 | /*** definitions ***/ |
33 | 34 | ||
34 | #define CHAR_WIDTH 6 | 35 | #define CHAR_WIDTH 6 |
35 | #define CHAR_HEIGHT 8 | 36 | #define CHAR_HEIGHT 8 |
36 | #define ICON_HEIGHT 8 | 37 | #define ICON_HEIGHT 10 |
37 | 38 | ||
38 | unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8]; | 39 | unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8]; |
39 | 40 | ||
40 | /* All zeros and ones bitmaps for area filling */ | ||
41 | static unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
42 | static unsigned char ones[8] = { 0xff, 0xff, 0xff, 0xff, | ||
43 | 0xff, 0xff, 0xff, 0xff}; | ||
44 | |||
45 | static int double_height=1; | 41 | static int double_height=1; |
46 | 42 | ||
47 | 43 | void lcd_print_icon(int x, int icon_line, bool enable, char **icon) | |
48 | /* | ||
49 | * Draw a bitmap at (x, y), size (nx, ny) | ||
50 | * if 'clear' is true, clear destination area first | ||
51 | */ | ||
52 | void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny, | ||
53 | bool clear) __attribute__ ((section (".icode"))); | ||
54 | void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny, | ||
55 | bool clear) | ||
56 | { | 44 | { |
57 | unsigned char *dst; | 45 | int xpos = x; |
58 | unsigned char *dst2; | 46 | int ypos = icon_line*(ICON_HEIGHT+CHAR_HEIGHT*2); |
59 | unsigned int data, mask, mask2, mask3, mask4; | 47 | int row=0, col; |
60 | int shift; | 48 | |
61 | 49 | while (icon[row]) { | |
62 | if (((unsigned)x >= LCD_WIDTH) || ((unsigned)y >= LCD_HEIGHT)) | 50 | col=0; |
63 | return; | 51 | while (icon[row][col]) { |
64 | if (((unsigned)(x + nx)) >= LCD_WIDTH) | 52 | lcd_framebuffer[xpos+col][(ypos+row)/8] &= ~(1<<((row+ypos)&7)); |
65 | nx = LCD_WIDTH - x; | 53 | if (enable) { |
66 | if (((unsigned)(y + ny)) >= LCD_HEIGHT) | 54 | if (icon[row][col]=='*') { |
67 | ny = LCD_HEIGHT - y; | 55 | lcd_framebuffer[xpos+col][(ypos+row)/8] |= 1<<((row+ypos)&7); |
68 | 56 | } | |
69 | shift = y & 7; | 57 | } |
70 | dst2 = &lcd_framebuffer[x][y/8]; | 58 | col++; |
71 | ny += shift; | ||
72 | |||
73 | /* Calculate bit masks */ | ||
74 | mask4 = ~(0xfe << ((ny-1) & 7)); | ||
75 | if (clear) | ||
76 | { | ||
77 | mask = ~(0xff << shift); | ||
78 | mask2 = 0; | ||
79 | mask3 = ~mask4; | ||
80 | if (ny <= 8) | ||
81 | mask3 |= mask; | ||
82 | } | 59 | } |
83 | else | 60 | row++; |
84 | mask = mask2 = mask3 = 0xff; | 61 | } |
85 | 62 | lcd_update(); | |
86 | /* Loop for each column */ | 63 | } |
87 | for (x = 0; x < nx; x++) | ||
88 | { | ||
89 | dst = dst2; | ||
90 | dst2 += LCD_HEIGHT/8; | ||
91 | data = 0; | ||
92 | y = 0; | ||
93 | |||
94 | if (ny > 8) | ||
95 | { | ||
96 | /* First partial row */ | ||
97 | data = *src++ << shift; | ||
98 | *dst = (*dst & mask) | data; | ||
99 | data >>= 8; | ||
100 | dst++; | ||
101 | |||
102 | /* Intermediate rows */ | ||
103 | for (y = 8; y < ny-8; y += 8) | ||
104 | { | ||
105 | data |= *src++ << shift; | ||
106 | *dst = (*dst & mask2) | data; | ||
107 | data >>= 8; | ||
108 | dst++; | ||
109 | } | ||
110 | } | ||
111 | 64 | ||
112 | /* Last partial row */ | 65 | void lcd_print_char(int x, int y, unsigned char ch) |
113 | if (y + shift < ny) | 66 | { |
114 | data |= *src++ << shift; | 67 | int xpos = x * CHAR_WIDTH; |
115 | *dst = (*dst & mask3) | (data & mask4); | 68 | int ypos = y * CHAR_HEIGHT; |
69 | int col, row; | ||
70 | int y2; | ||
71 | // double_height=2; | ||
72 | if (double_height == 2 && y == 1) | ||
73 | return; /* Second row can't be printed in double height. ??*/ | ||
74 | |||
75 | xpos*=2; | ||
76 | |||
77 | /* printf("(%d,%d)='%d'\n", x, y, ch);*/ | ||
78 | for (col=0; col<5; col++) { | ||
79 | for (row=0; row<7; row++) { | ||
80 | for (y2=0; y2<double_height*2; y2++) { | ||
81 | int y; | ||
82 | unsigned char bitval; | ||
83 | |||
84 | if (double_height*row >=7) | ||
85 | y2+=double_height; | ||
86 | y=y2+double_height*2*row+2*ypos+ICON_HEIGHT; | ||
87 | |||
88 | bitval=3<<((y&6)); | ||
89 | if (font_player[ch][col]&(1<<row)) { | ||
90 | lcd_framebuffer[xpos+col*2][y/8] |= bitval; | ||
91 | |||
92 | } else { | ||
93 | lcd_framebuffer[xpos+col*2][y/8] &= ~bitval; | ||
94 | } | ||
95 | lcd_framebuffer[xpos+col*2+1][y/8] = | ||
96 | lcd_framebuffer[xpos+col*2][y/8]; | ||
97 | } | ||
116 | } | 98 | } |
99 | } | ||
117 | } | 100 | } |
118 | 101 | ||
119 | /* | 102 | |
103 | /* | ||
120 | * Draw a rectangle with upper left corner at (x, y) | 104 | * Draw a rectangle with upper left corner at (x, y) |
121 | * and size (nx, ny) | 105 | * and size (nx, ny) |
122 | */ | 106 | */ |
@@ -147,26 +131,6 @@ void lcd_drawrect (int x, int y, int nx, int ny) | |||
147 | } | 131 | } |
148 | } | 132 | } |
149 | 133 | ||
150 | /* | ||
151 | * Clear a rectangular area at (x, y), size (nx, ny) | ||
152 | */ | ||
153 | void lcd_clearrect (int x, int y, int nx, int ny) | ||
154 | { | ||
155 | int i; | ||
156 | for (i = 0; i < nx; i++) | ||
157 | lcd_bitmap (zeros, x+i, y, 1, ny, true); | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Fill a rectangular area at (x, y), size (nx, ny) | ||
162 | */ | ||
163 | void lcd_fillrect (int x, int y, int nx, int ny) | ||
164 | { | ||
165 | int i; | ||
166 | for (i = 0; i < nx; i++) | ||
167 | lcd_bitmap (ones, x+i, y, 1, ny, true); | ||
168 | } | ||
169 | |||
170 | /* Invert a rectangular area at (x, y), size (nx, ny) */ | 134 | /* Invert a rectangular area at (x, y), size (nx, ny) */ |
171 | void lcd_invertrect (int x, int y, int nx, int ny) | 135 | void lcd_invertrect (int x, int y, int nx, int ny) |
172 | { | 136 | { |
@@ -356,79 +320,13 @@ void lcd_clear_display(void) | |||
356 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); | 320 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); |
357 | } | 321 | } |
358 | 322 | ||
359 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | ||
360 | static void lcd_putsxyofs(int x, int y, int ofs, unsigned char *str) | ||
361 | { | ||
362 | int ch; | ||
363 | struct font* pf = font_get(2); | ||
364 | |||
365 | while ((ch = *str++) != '\0' && x < LCD_WIDTH) | ||
366 | { | ||
367 | int width; | ||
368 | |||
369 | /* check input range */ | ||
370 | if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) | ||
371 | ch = pf->defaultchar; | ||
372 | ch -= pf->firstchar; | ||
373 | |||
374 | /* no partial-height drawing for now... */ | ||
375 | if (y + pf->height > LCD_HEIGHT) | ||
376 | break; | ||
377 | |||
378 | /* get proportional width and glyph bits */ | ||
379 | width = pf->width ? pf->width[ch] : pf->maxwidth; | ||
380 | width = MIN (width, LCD_WIDTH - x); | ||
381 | |||
382 | if (ofs != 0) | ||
383 | { | ||
384 | if (ofs > width) | ||
385 | { | ||
386 | ofs -= width; | ||
387 | continue; | ||
388 | } | ||
389 | width -= ofs; | ||
390 | } | ||
391 | |||
392 | if (width > 0) | ||
393 | { | ||
394 | int rows = (pf->height + 7) / 8; | ||
395 | bitmap_t* bits = pf->bits + | ||
396 | (pf->offset ? pf->offset[ch] : (pf->height * ch)); | ||
397 | lcd_bitmap (((unsigned char*) bits) + ofs*rows, x, y, | ||
398 | width, pf->height, true); | ||
399 | x += width; | ||
400 | } | ||
401 | ofs = 0; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* put a string at a given pixel position */ | ||
406 | void lcd_putsxy(int x, int y, unsigned char *str) | ||
407 | { | ||
408 | lcd_putsxyofs(x, y, 0, str); | ||
409 | } | ||
410 | |||
411 | void lcd_puts(int x, int y, unsigned char *str) | 323 | void lcd_puts(int x, int y, unsigned char *str) |
412 | { | 324 | { |
413 | int xpos,ypos; | 325 | int i; |
414 | 326 | for (i=0; *str && x<11; i++) | |
415 | /* We make the simulator truncate the string if it reaches the right edge, | 327 | lcd_print_char(x++, y, *str++); |
416 | as otherwise it'll wrap. The real target doesn't wrap. */ | 328 | for (; x<11; x++) |
417 | 329 | lcd_print_char(x, y, ' '); | |
418 | char buffer[12]; | ||
419 | if(strlen(str)+x > 11 ) { | ||
420 | strncpy(buffer, str, sizeof buffer); | ||
421 | buffer[11-x]=0; | ||
422 | str = buffer; | ||
423 | } | ||
424 | |||
425 | xpos = CHAR_WIDTH * x; | ||
426 | ypos = ICON_HEIGHT + CHAR_HEIGHT * y; | ||
427 | lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, CHAR_HEIGHT * double_height); | ||
428 | lcd_putsxy(xpos, ypos, str); | ||
429 | |||
430 | /* this function is being used when simulating a charcell LCD and | ||
431 | then we update immediately */ | ||
432 | lcd_update(); | 330 | lcd_update(); |
433 | } | 331 | } |
434 | 332 | ||
@@ -439,15 +337,13 @@ void lcd_double_height(bool on) | |||
439 | double_height = 2; | 337 | double_height = 2; |
440 | } | 338 | } |
441 | 339 | ||
442 | static char patterns[8][7]; | ||
443 | |||
444 | void lcd_define_pattern(int which, char *pattern, int length) | 340 | void lcd_define_pattern(int which, char *pattern, int length) |
445 | { | 341 | { |
446 | int i, j; | 342 | int i, j; |
447 | int pat = which / 8; | 343 | int pat = which / 8; |
448 | char icon[8]; | 344 | char icon[8]; |
449 | memset(icon, 0, sizeof icon); | 345 | memset(icon, 0, sizeof icon); |
450 | 346 | ||
451 | DEBUGF("Defining pattern %d\n", pat); | 347 | DEBUGF("Defining pattern %d\n", pat); |
452 | for (j = 0; j <= 5; j++) { | 348 | for (j = 0; j <= 5; j++) { |
453 | for (i = 0; i < length; i++) { | 349 | for (i = 0; i < length; i++) { |
@@ -455,42 +351,16 @@ void lcd_define_pattern(int which, char *pattern, int length) | |||
455 | icon[5-j] |= (1<<(i)); | 351 | icon[5-j] |= (1<<(i)); |
456 | } | 352 | } |
457 | } | 353 | } |
458 | for (i = 0; i <= 5; i++) | 354 | for (i = 1; i <= 5; i++) |
459 | { | 355 | { |
460 | patterns[pat][i] = icon[i]; | 356 | font_player[pat][i-1] = icon[i]; |
461 | } | 357 | } |
462 | } | 358 | } |
463 | 359 | ||
464 | char* get_lcd_pattern(int which) | ||
465 | { | ||
466 | DEBUGF("Get pattern %d\n", which); | ||
467 | return patterns[which]; | ||
468 | } | ||
469 | |||
470 | extern void lcd_puts(int x, int y, unsigned char *str); | 360 | extern void lcd_puts(int x, int y, unsigned char *str); |
471 | 361 | ||
472 | void lcd_putc(int x, int y, unsigned char ch) | 362 | void lcd_putc(int x, int y, unsigned char ch) |
473 | { | 363 | { |
474 | char str[2]; | 364 | lcd_print_char(x, y, ch); |
475 | int xpos = x * CHAR_WIDTH; | ||
476 | int ypos = ICON_HEIGHT + y * CHAR_HEIGHT; | ||
477 | if (ch <= 8) | ||
478 | { | ||
479 | char* bm = get_lcd_pattern(ch); | ||
480 | lcd_bitmap(bm, xpos, ypos, CHAR_WIDTH, CHAR_HEIGHT, true); | ||
481 | return; | ||
482 | } | ||
483 | if (ch == 137) { | ||
484 | /* Have no good font yet. Simulate the cursor character. */ | ||
485 | ch = '>'; | ||
486 | } | ||
487 | str[0] = ch; | ||
488 | str[1] = 0; | ||
489 | |||
490 | lcd_clearrect(xpos, ypos, CHAR_WIDTH, CHAR_HEIGHT * double_height); | ||
491 | lcd_putsxy(xpos, ypos, str); | ||
492 | |||
493 | /* this function is being used when simulating a charcell LCD and | ||
494 | then we update immediately */ | ||
495 | lcd_update(); | 365 | lcd_update(); |
496 | } | 366 | } |