@@ -880,14 +880,23 @@ void display_print_in_area(const char* st, int x, int y, dispWin_t areaWin, bool
880880 }
881881}
882882
883- #define GRAY_MASK1 0xF8
884- #define GRAY_MASK2 0xFC
885-
886- static inline uint16_t uint8_to_uint16_color (uint8_t gray )
887- {
888- const uint16_t res = ((gray & GRAY_MASK1 ) << 8 ) | ((gray & GRAY_MASK2 ) << 3 ) | ((gray & GRAY_MASK1 ) >> 3 );
889- return __builtin_bswap16 (res );
890- }
883+ // Macros to convert a grayscale 0-255 index to big-endian 565 RGB
884+ #define GS_MASK1 0xF8
885+ #define GS_MASK2 0xFC
886+ #define GS_CPU (n ) (((n & GS_MASK1) << 8) | ((n & GS_MASK2) << 3) | ((n & GS_MASK1) >> 3))
887+ // TODO: this should just be GS_CPU(n) if our arch is natively big-endian
888+ #define GS (n ) ((GS_CPU(n) & 0x00ff) << 8) | ((GS_CPU(n) & 0xff00) >> 8)
889+
890+ // We have 6 bits max per R/G/B, so only need 64 distinct mappings
891+ static const uint16_t gray_565 [64 ] = { GS (0 ), GS (4 ), GS (8 ), GS (12 ), GS (16 ), GS (20 ), GS (24 ), GS (28 ), GS (32 ), GS (36 ),
892+ GS (40 ), GS (44 ), GS (48 ), GS (52 ), GS (56 ), GS (60 ), GS (64 ), GS (68 ), GS (72 ), GS (76 ), GS (80 ), GS (84 ), GS (88 ), GS (92 ),
893+ GS (96 ), GS (100 ), GS (104 ), GS (108 ), GS (112 ), GS (116 ), GS (120 ), GS (124 ), GS (128 ), GS (132 ), GS (136 ), GS (140 ), GS (144 ),
894+ GS (148 ), GS (152 ), GS (156 ), GS (160 ), GS (164 ), GS (168 ), GS (172 ), GS (176 ), GS (180 ), GS (184 ), GS (188 ), GS (192 ), GS (196 ),
895+ GS (200 ), GS (204 ), GS (208 ), GS (212 ), GS (216 ), GS (220 ), GS (224 ), GS (228 ), GS (232 ), GS (236 ), GS (240 ), GS (244 ), GS (248 ),
896+ GS (252 ) };
897+
898+ #undef GS_CPU
899+ #undef GS
891900
892901void display_picture (const Picture * imgbuf , int x , int y , dispWin_t area )
893902{
@@ -942,11 +951,15 @@ void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area)
942951 color_t * hw_buf = display_hw_get_buffer ();
943952 const int offsetx = calculatedx - CONFIG_DISPLAY_OFFSET_X ;
944953 const int offsety = calculatedy - CONFIG_DISPLAY_OFFSET_Y ;
945- uint16_t * screen_ptr = & hw_buf [offsetx + offsety * CONFIG_DISPLAY_WIDTH ];
954+ uint16_t * disp_ptr = & hw_buf [offsetx + offsety * CONFIG_DISPLAY_WIDTH ];
955+ const uint8_t * src_ptr = imgbuf -> data_8 ;
956+ const uint16_t stride = CONFIG_DISPLAY_WIDTH - imgbuf -> width ;
946957 for (size_t i = 0 ; i < imgbuf -> height ; ++ i ) {
947958 for (size_t k = 0 ; k < imgbuf -> width ; ++ k ) {
948- screen_ptr [k + i * CONFIG_DISPLAY_WIDTH ] = uint8_to_uint16_color (imgbuf -> data_8 [k + imgbuf -> width * i ]);
959+ * disp_ptr ++ = gray_565 [* src_ptr >> 2 ];
960+ ++ src_ptr ;
949961 }
962+ disp_ptr += stride ;
950963 }
951964#else
952965
@@ -960,7 +973,8 @@ void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area)
960973 const uint8_t * src_ptr = imgbuf -> data_8 + line_offset * imgbuf -> width ;
961974
962975 for (int i = 0 ; i < maximum_lines * imgbuf -> width ; ++ i ) {
963- * disp_ptr ++ = uint8_to_uint16_color (* src_ptr ++ );
976+ * disp_ptr ++ = gray_565 [* src_ptr >> 2 ];
977+ ++ src_ptr ;
964978 }
965979
966980 draw_bitmap (calculatedx , calculatedy + line_offset , imgbuf -> width , maximum_lines , disp_buf );
0 commit comments