44#include <stdio.h>
55#include <stdarg.h>
66
7+ #ifdef MCP_RECOVERY
8+ // mcp_recovery does something different with framebuffer handling.
9+ // Only TV is usable; DRC isn't initialized.
10+ static uint32_t * framebuffer ;
11+ static uint32_t width ;
12+ static uint32_t height ;
13+ #else /* !MCP_RECOVERY */
14+
715static uint32_t * const TV_FRAMEBUFFER = (uint32_t * )(0x14000000 + 0x3500000 );
816#define TV_HEIGHT 720
917#define TV_STRIDE 1280
@@ -12,6 +20,8 @@ static uint32_t* const DRC_FRAMEBUFFER = (uint32_t*)(0x14000000 + 0x38c0000);
1220#define DRC_HEIGHT 480
1321#define DRC_STRIDE 896
1422
23+ #endif /* MCP_RECOVERY */
24+
1525#define CHAR_SIZE_TV_X 12
1626#define CHAR_SIZE_TV_Y 24
1727
@@ -50,53 +60,90 @@ int gfx_init_font(void)
5060 return 0 ;
5161}
5262
63+ #ifdef MCP_RECOVERY
64+ void gfx_init (void * fb , uint32_t w , uint32_t h )
65+ {
66+ framebuffer = (uint32_t * ) fb ;
67+ width = w ;
68+ height = h ;
69+ }
70+ #endif /* MCP_RECOVERY */
71+
5372void gfx_clear (uint32_t col )
5473{
55- #ifdef DC_INIT
74+ #if defined( DC_INIT ) || defined( MCP_RECOVERY )
5675 // both DC configurations use XRGB instead of RGBX
5776 col >>= 8 ;
58- #endif
77+ #endif /* DC_INIT || MCP_RECOVERY */
5978
79+ #ifdef MCP_RECOVERY
80+ for (uint32_t i = 0 ; i < width * height ; i ++ ) {
81+ framebuffer [i ] = col ;
82+ }
83+ #else /* !MCP_RECOVERY */
6084 for (uint32_t i = 0 ; i < TV_STRIDE * TV_HEIGHT ; i ++ ) {
6185 TV_FRAMEBUFFER [i ] = col ;
6286 }
6387
6488 for (uint32_t i = 0 ; i < DRC_STRIDE * DRC_HEIGHT ; i ++ ) {
6589 DRC_FRAMEBUFFER [i ] = col ;
6690 }
91+ #endif /* MCP_RECOVERY */
6792}
6893
6994void gfx_draw_pixel (uint32_t x , uint32_t y , uint32_t col )
7095{
71- #ifdef DC_INIT
96+ #if defined( DC_INIT ) || defined( MCP_RECOVERY )
7297 // both DC configurations use XRGB instead of RGBX
7398 col >>= 8 ;
74- #endif
99+ #endif /* DC_INIT || MCP_RECOVERY */
75100
101+ #ifndef MCP_RECOVERY
76102 // put pixel in the drc buffer
77103 uint32_t i = x + y * DRC_STRIDE ;
78104 if (i < DRC_STRIDE * DRC_HEIGHT ) {
79105 DRC_FRAMEBUFFER [i ] = col ;
80106 }
107+ #endif /* !MCP_RECOVERY */
81108
82109 // scale and put pixel in the tv buffer
83110 for (uint32_t yy = (y * 1.5f ); yy < ((y * 1.5f ) + 1 ); yy ++ ) {
84111 for (uint32_t xx = (x * 1.5f ); xx < ((x * 1.5f ) + 1 ); xx ++ ) {
112+ #ifdef MCP_RECOVERY
113+ uint32_t i = xx + yy * width ;
114+ if (i < width * height ) {
115+ framebuffer [i ] = col ;
116+ }
117+ #else /* !MCP_RECOVERY */
85118 uint32_t i = xx + yy * TV_STRIDE ;
86119 if (i < TV_STRIDE * TV_HEIGHT ) {
87120 TV_FRAMEBUFFER [i ] = col ;
88121 }
122+ #endif /* MCP_RECOVERY */
89123 }
90124 }
91125}
92126
93127void gfx_draw_rect_filled (uint32_t x , uint32_t y , uint32_t w , uint32_t h , uint32_t col )
94128{
95- #ifdef DC_INIT
129+ #if defined( DC_INIT ) || defined( MCP_RECOVERY )
96130 // both DC configurations use XRGB instead of RGBX
97131 col >>= 8 ;
98- #endif
132+ #endif /* DC_INIT || MCP_RECOVERY */
133+
134+ #ifdef MCP_RECOVERY
135+ // mcp_recovery: Using TV scale because mcp_recovery seems to have a
136+ // 1280x720 framebuffer, even though the output mode is usually 480p.
137+ uint32_t * p = framebuffer + ((uint32_t )(y * 1.5f ) * width ) + (uint32_t )(x * 1.5f );
138+ uint32_t stride_diff = width - (w * 1.5f );
99139
140+ for (uint32_t hcnt = (h * 1.5f ); hcnt > 0 ; hcnt -- ) {
141+ for (uint32_t wcnt = (w * 1.5f ); wcnt > 0 ; wcnt -- ) {
142+ * p ++ = col ;
143+ }
144+ p += stride_diff ;
145+ }
146+ #else /* !MCP_RECOVERY */
100147 // DRC fill: normal scale
101148 uint32_t * p = DRC_FRAMEBUFFER + (y * DRC_STRIDE ) + x ;
102149 uint32_t stride_diff = DRC_STRIDE - w ;
@@ -118,6 +165,7 @@ void gfx_draw_rect_filled(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32
118165 }
119166 p += stride_diff ;
120167 }
168+ #endif /* MCP_RECOVERY */
121169}
122170
123171void gfx_draw_rect (uint32_t x , uint32_t y , uint32_t w , uint32_t h , uint32_t borderSize , uint32_t col )
@@ -130,10 +178,10 @@ void gfx_draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t bord
130178
131179void gfx_set_font_color (uint32_t col )
132180{
133- #ifdef DC_INIT
181+ #if defined( DC_INIT ) || defined( MCP_RECOVERY )
134182 // both DC configurations use XRGB instead of RGBX
135183 col >>= 8 ;
136- #endif
184+ #endif /* DC_INIT || MCP_RECOVERY */
137185
138186 font_color = col ;
139187}
@@ -152,6 +200,25 @@ static void gfx_draw_char(uint32_t x, uint32_t y, char c)
152200 return ;
153201 c -= 32 ;
154202
203+ #ifdef MCP_RECOVERY
204+ // mcp_recovery: Terminus 12x24 bold
205+ // Using TV scale because mcp_recovery seems to have a 1280x720
206+ // framebuffer, even though the output mode is usually 480p.
207+ const uint16_t * charMCP = font -> ter_u24b [(unsigned char )c ];
208+ uint32_t * p = framebuffer + ((uint32_t )(y * 1.5f ) * width ) + (uint32_t )(x * 1.5f );
209+ unsigned int stride_diff = width - CHAR_SIZE_TV_X ;
210+
211+ for (uint32_t hcnt = CHAR_SIZE_TV_Y ; hcnt > 0 ; hcnt -- ) {
212+ uint16_t v = * charMCP ++ ;
213+ for (uint32_t wcnt = CHAR_SIZE_TV_X ; wcnt > 0 ; wcnt -- , v >>= 1 ) {
214+ if (v & 1 ) {
215+ * p = font_color ;
216+ }
217+ p ++ ;
218+ }
219+ p += stride_diff ;
220+ }
221+ #else /* !MCP_RECOVERY */
155222 // DRC blit: Terminus 8x16 bold
156223 const uint8_t * charDRC = font -> ter_u16b [(unsigned char )c ];
157224 uint32_t * p = DRC_FRAMEBUFFER + (y * DRC_STRIDE ) + x ;
@@ -183,6 +250,7 @@ static void gfx_draw_char(uint32_t x, uint32_t y, char c)
183250 }
184251 p += stride_diff ;
185252 }
253+ #endif /* !MCP_RECOVERY */
186254}
187255
188256/**
0 commit comments