summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
index 3ecd7df4e8..f323dda1e1 100644
--- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
@@ -8,7 +8,11 @@
8#include <stdlib.h> 8#include <stdlib.h>
9#include "memory.h" 9#include "memory.h"
10#include "lcd-target.h" 10#include "lcd-target.h"
11#include "font.h"
12#include "rbunicode.h"
13#include "bidi.h"
11 14
15#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
12/* 16/*
13** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups 17** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups
14*/ 18*/
@@ -235,6 +239,159 @@ void lcd_update(void)
235 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 239 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
236} 240}
237 241
242void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
243 int stride, int x, int y, int width,
244 int height)
245{
246 fb_data *dst, *dst_end;
247 unsigned int transcolor;
248
249 /* nothing to draw? */
250 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
251 || (x + width <= 0) || (y + height <= 0))
252 return;
253
254 /* clipping */
255 if (x < 0)
256 {
257 width += x;
258 src_x -= x;
259 x = 0;
260 }
261 if (y < 0)
262 {
263 height += y;
264 src_y -= y;
265 y = 0;
266 }
267 if (x + width > LCD_WIDTH)
268 width = LCD_WIDTH - x;
269 if (y + height > LCD_HEIGHT)
270 height = LCD_HEIGHT - y;
271
272 src += stride * src_y + src_x; /* move starting point */
273 dst = &lcd_framebuffer[(y)][(x)];
274 dst_end = dst + height * LCD_WIDTH;
275 width *= 2;
276 stride *= 2;
277 transcolor = TRANSPARENT_COLOR;
278 asm volatile(
279 "rowstart: \n"
280 "mov r0, #0 \n"
281 "nextpixel: \n"
282 "ldrh r1, [%0, r0] \n" /* Load word src+r0 */
283 "cmp r1, %5 \n" /* Compare to transparent color */
284 "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */
285 "add r0, r0, #2 \n"
286 "cmp r0, %2 \n" /* r0 == width? */
287 "bne nextpixel \n" /* More in this row? */
288 "add %0, %0, %4 \n" /* src += stride */
289 "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */
290 "cmp %1, %3 \n"
291 "bne rowstart \n" /* if(dst != dst_end), keep going */
292 : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" );
293}
294
295void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
296 int stride, int x, int y, int width, int height)
297 ICODE_ATTR;
298void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
299 int stride, int x, int y, int width, int height)
300{
301 const unsigned char *src_end;
302 fb_data *dst, *dst_end;
303
304 /* nothing to draw? */
305 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
306 || (x + width <= 0) || (y + height <= 0))
307 return;
308
309 /* clipping */
310 if (x < 0)
311 {
312 width += x;
313 src_x -= x;
314 x = 0;
315 }
316 if (y < 0)
317 {
318 height += y;
319 src_y -= y;
320 y = 0;
321 }
322 if (x + width > LCD_WIDTH)
323 width = LCD_WIDTH - x;
324 if (y + height > LCD_HEIGHT)
325 height = LCD_HEIGHT - y;
326
327 src += stride * (src_y >> 3) + src_x; /* move starting point */
328 src_y &= 7;
329 src_end = src + width;
330
331 dst = LCDADDR(x, y);
332 int drawmode = lcd_get_drawmode();
333 if(drawmode == DRMODE_SOLID) {
334 do
335 {
336 const unsigned char *src_col = src++;
337 unsigned data = *src_col >> src_y;
338 fb_data *dst_col = dst++;
339 int numbits = 8 - src_y;
340
341 dst_end = dst_col + height * LCD_WIDTH;
342 asm volatile(
343 "transrowstart: \n"
344 "tst %0, #1 \n" /* Test data bit 1 */
345 "strneh %6, [%1] \n" /* If it is set, set pixel */
346 "add %1, %1, #480 \n" /* dst_col += LCD_WIDTH (x2) */
347 "sub %7, %7, #1 \n" /* numbits-- */
348 "cmp %7, #0 \n"
349 "movne %0, %0, LSR #1 \n" /* Shift data */
350 "bne transrowstart \n" /* if(numbits != 0) goto transrowstart */
351 "add %5, %5, %4 \n" /* src_col += stride */
352 "ldrb %0, [%5] \n" /* data = *srccol */
353 "mov %7, #8 \n" /* numbits = 8; */
354 "cmp %1, %3 \n" /* if(dst_col < dst_end */
355 "blt transrowstart \n" /* Keep going */
356 : : "r" (data), "r" (dst_col), "r" (numbits), "r" (dst_end), "r" (stride), "r" (src_col), "r" (fg_pattern), "r" (numbits) );
357 }
358 while (src < src_end);
359 }
360 else {
361 lcd_fastpixelfunc_type *fgfunc = lcd_fastpixelfuncs[drawmode];;
362 lcd_fastpixelfunc_type *bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];;
363 do
364 {
365 const unsigned char *src_col = src++;
366 unsigned data = *src_col >> src_y;
367 fb_data *dst_col = dst++;
368 int numbits = 8 - src_y;
369
370 dst_end = dst_col + height * LCD_WIDTH;
371 do
372 {
373 if (data & 0x01)
374 fgfunc(dst_col);
375 else
376 bgfunc(dst_col);
377
378 dst_col += LCD_WIDTH;
379
380 data >>= 1;
381 if (--numbits == 0)
382 {
383 src_col += stride;
384 data = *src_col;
385 numbits = 8;
386 }
387 }
388 while (dst_col < dst_end);
389 }
390 while (src < src_end);
391 }
392}
393
394
238#define CSUB_X 2 395#define CSUB_X 2
239#define CSUB_Y 2 396#define CSUB_Y 2
240 397