@@ -277,6 +277,10 @@ void lcdMemLCD_flip_spi_callback() {
277277 jshPinSetValue (LCD_SPI_CS , 0 );
278278 lcdIsBusy = false;
279279}
280+ // Mirror X - use when doing overlays when screen is rotated 180
281+ static void _lcdMemLCD_setPixel_mirrored (JsGraphics * gfx , int x , int y , unsigned int col ) {
282+ lcdMemLCD_setPixel (gfx , (LCD_WIDTH - 1 )- x , y , col );
283+ }
280284// send the data to the screen
281285void lcdMemLCD_flip (JsGraphics * gfx ) {
282286 if (gfx -> data .modMinY > gfx -> data .modMaxY ) return ; // nothing to do!
@@ -320,44 +324,38 @@ void lcdMemLCD_flip(JsGraphics *gfx) {
320324 // Take account of rotation - only check for a full 180 rotation - doing 90 is too hard
321325 bool isRotated180 = (graphicsInternal .data .flags & (JSGRAPHICSFLAGS_SWAP_XY | JSGRAPHICSFLAGS_INVERT_X | JSGRAPHICSFLAGS_INVERT_Y )) ==
322326 (JSGRAPHICSFLAGS_INVERT_X | JSGRAPHICSFLAGS_INVERT_Y );
323- int ovY = isRotated180 ? (LCD_HEIGHT - (lcdOverlayY + overlayImg .height )) : lcdOverlayY ;
324- // initialise image layer
325- GfxDrawImageLayer l ;
326- l .x1 = 0 ;
327- l .y1 = ovY * 256 ;
328- l .img = overlayImg ;
329- l .rotate = isRotated180 ? 3.141592 : 0 ;
330- l .scale = 1 ;
331- l .center = false;
332- l .repeat = false;
333- jsvStringIteratorNew (& l .it , l .img .buffer , (size_t )l .img .bitmapOffset );
334- _jswrap_drawImageLayerInit (& l );
335- _jswrap_drawImageLayerSetStart (& l , 0 , y1 );
336- for (int y = y1 ;y <=y2 ;y ++ ) {
327+ int ovY = lcdOverlayY ;
328+ int yd = 1 ;
329+ JsGraphicsSetPixelFn setPixel = lcdMemLCD_setPixel ;
330+ int bits = (ovY < y1 ) ? (ovY - y1 )* overlayImg .bpp * overlayImg .width : 0 ;
331+ uint32_t colData ;
332+ if (isRotated180 ) {
333+ yd = -1 ;
334+ int y = y1 ;
335+ y1 = y2 ;
336+ y2 = y - 1 ;
337+ ovY = LCD_HEIGHT - (lcdOverlayY + overlayImg .height );
338+ setPixel = _lcdMemLCD_setPixel_mirrored ;
339+ } else y2 ++ ;
340+ JsvStringIterator it ;
341+ jsvStringIteratorNew (& it , overlayImg .buffer , (size_t )overlayImg .bitmapOffset );
342+ for (int y = y1 ;y != y2 ;y += yd ) {
337343 int bufferLine = LCD_HEIGHT + (y & 1 ); // alternate lines so we still get dither AND we can send while calculating next line
338344 unsigned char * buf = & lcdBuffer [LCD_STRIDE * bufferLine ]; // point to line right on the end of gfx
339345 // copy original line in
340346 memcpy (buf , & lcdBuffer [LCD_STRIDE * y ], LCD_STRIDE );
341347 // overwrite areas with overlay image
342348 if (y >=ovY && y < ovY + overlayImg .height ) {
343- _jswrap_drawImageLayerStartX (& l );
344- for (int x = 0 ;x < overlayImg .width ;x ++ ) {
345- uint32_t c ;
346- int ox = x + lcdOverlayX ;
347- if (_jswrap_drawImageLayerGetPixel (& l , & c ) && (ox < LCD_WIDTH ) && (ox >= 0 ))
348- lcdMemLCD_setPixel (NULL , ox , bufferLine , c );
349- _jswrap_drawImageLayerNextX (& l );
350- }
349+ _jswrap_drawImageSimpleRow (gfx , lcdOverlayX , bufferLine , & overlayImg , & it , lcdMemLCD_setPixel , & bits , & colData );
351350 }
352- _jswrap_drawImageLayerNextY (& l );
353351 // send the line
354352#ifdef EMULATED
355353 memcpy (& fakeLCDBuffer [LCD_STRIDE * y ], buf , LCD_STRIDE );
356354#else
357355 jshSPISendMany (LCD_SPI , buf , NULL , LCD_STRIDE , lcdMemLCD_flip_spi_ovr_callback );
358356#endif
359357 }
360- jsvStringIteratorFree (& l . it );
358+ jsvStringIteratorFree (& it );
361359 _jswrap_graphics_freeImageInfo (& overlayImg );
362360 // and 2 final bytes to finish the transfer
363361#ifndef EMULATED
0 commit comments