@@ -765,6 +765,49 @@ void tic80_libretro_update_mouse(tic80_mouse* mouse)
765765 mouse -> y = state -> mouseY + TIC80_OFFSET_TOP ;
766766}
767767
768+ /**
769+ * Gets the 32-bit color value from the TIC-80 palette.
770+ */
771+ static u32 get_screen_color (tic_mem * tic , u8 index )
772+ {
773+ tic_rgb color = tic -> ram -> vram .palette .colors [index ];
774+ // The core requests RETRO_PIXEL_FORMAT_XRGB8888, so we format the color as 0x00RRGGBB.
775+ return (color .r << 16 ) | (color .g << 8 ) | (color .b );
776+ }
777+
778+ /**
779+ * Draws a single pixel directly to the final screen buffer.
780+ */
781+ static void draw_pixel_on_screen (u32 * screen , s32 x , s32 y , u32 color )
782+ {
783+ // Bounds check against the visible screen area
784+ if (x < 0 || x >= TIC80_WIDTH || y < 0 || y >= TIC80_HEIGHT )
785+ return ;
786+
787+ s32 full_x = x + TIC80_OFFSET_LEFT ;
788+ s32 full_y = y + TIC80_OFFSET_TOP ;
789+
790+ screen [full_y * TIC80_FULLWIDTH + full_x ] = color ;
791+ }
792+
793+ /**
794+ * Draws a horizontal line directly to the final screen buffer.
795+ */
796+ static void draw_hline_on_screen (u32 * screen , s32 x1 , s32 x2 , s32 y , u32 color )
797+ {
798+ for (s32 x = x1 ; x <= x2 ; x ++ )
799+ draw_pixel_on_screen (screen , x , y , color );
800+ }
801+
802+ /**
803+ * Draws a vertical line directly to the final screen buffer.
804+ */
805+ static void draw_vline_on_screen (u32 * screen , s32 x , s32 y1 , s32 y2 , u32 color )
806+ {
807+ for (s32 y = y1 ; y <= y2 ; y ++ )
808+ draw_pixel_on_screen (screen , x , y , color );
809+ }
810+
768811/**
769812 * Draws a software cursor on the screen where the mouse is.
770813 */
@@ -777,26 +820,45 @@ void tic80_libretro_mousecursor(tic80* game, tic80_mouse* mouse, enum mouse_curs
777820 return ;
778821 }
779822
780- tic_mem * tic = (tic_mem * )state -> tic ;
823+ tic_mem * tic = (tic_mem * )game ;
824+ u32 * screen = game -> screen ;
825+ s32 mx = state -> mouseX ;
826+ s32 my = state -> mouseY ;
827+
828+ // Calculate the final 32-bit color value
829+ u32 cursor_color = get_screen_color (tic , state -> mouseCursorColor );
781830
782- // Draw the cursor.
783- // TODO: Fix the cursor not being drawn on the screen by possibly modifing game->screen directly.
831+ // Draw the cursor directly to the screen buffer.
784832 switch (cursortype ) {
785833 case MOUSE_CURSOR_NONE :
786834 // Nothing.
787835 break ;
788836 case MOUSE_CURSOR_DOT :
789- tic_api_pix ( tic , state -> mouseX , state -> mouseY , state -> mouseCursorColor , false );
837+ draw_pixel_on_screen ( screen , mx , my , cursor_color );
790838 break ;
791839 case MOUSE_CURSOR_CROSS :
792- tic_api_line ( tic , state -> mouseX - 4 , state -> mouseY , state -> mouseX - 2 , state -> mouseY , state -> mouseCursorColor );
793- tic_api_line ( tic , state -> mouseX + 2 , state -> mouseY , state -> mouseX + 4 , state -> mouseY , state -> mouseCursorColor );
794- tic_api_line ( tic , state -> mouseX , state -> mouseY - 4 , state -> mouseX , state -> mouseY - 2 , state -> mouseCursorColor );
795- tic_api_line ( tic , state -> mouseX , state -> mouseY + 2 , state -> mouseX , state -> mouseY + 4 , state -> mouseCursorColor );
840+ draw_hline_on_screen ( screen , mx - 4 , mx - 2 , my , cursor_color );
841+ draw_hline_on_screen ( screen , mx + 2 , mx + 4 , my , cursor_color );
842+ draw_vline_on_screen ( screen , mx , my - 4 , my - 2 , cursor_color );
843+ draw_vline_on_screen ( screen , mx , my + 2 , my + 4 , cursor_color );
796844 break ;
797845 case MOUSE_CURSOR_ARROW :
798- tic_api_tri (tic , state -> mouseX , state -> mouseY , state -> mouseX + 3 , state -> mouseY , state -> mouseX , state -> mouseY + 3 , state -> mouseCursorColor );
799- tic_api_line (tic , state -> mouseX + 3 , state -> mouseY , state -> mouseX , state -> mouseY + 3 , tic_color_black );
846+ {
847+ // Calculate black for the outline.
848+ u32 black_color = get_screen_color (tic , tic_color_black );
849+
850+ // Draw the filled triangle part of the arrow
851+ for (int y = 0 ; y <= 2 ; y ++ ) {
852+ for (int x = 0 ; x <= 2 - y ; x ++ ) {
853+ draw_pixel_on_screen (screen , mx + x , my + y , cursor_color );
854+ }
855+ }
856+ // Draw the black outline (hypotenuse of the triangle)
857+ draw_pixel_on_screen (screen , mx + 3 , my , black_color );
858+ draw_pixel_on_screen (screen , mx + 2 , my + 1 , black_color );
859+ draw_pixel_on_screen (screen , mx + 1 , my + 2 , black_color );
860+ draw_pixel_on_screen (screen , mx , my + 3 , black_color );
861+ }
800862 break ;
801863 }
802864}
@@ -972,7 +1034,7 @@ void tic80_libretro_variables(bool startup)
9721034 state -> mouseHideTimerStart = atoi (var .value );
9731035 if (state -> mouseHideTimerStart > 0 ) {
9741036 state -> mouseHideTimerStart = state -> mouseHideTimerStart * TIC80_FRAMERATE ;
975- state -> mouseHideTimer = state -> mouseHideTimerStart ;
1037+ state -> mouseHideTimer = 0 ; // Cursor starts hidden
9761038 }
9771039 else {
9781040 state -> mouseHideTimerStart = 0 ;
0 commit comments