+\r
+/**\r
+ * \brief Updates the state of the text cursor\r
+ * \note Just does a bitwise not on the cursor region\r
+ */\r
+void Vesa_FlipCursor(void *Arg)\r
+{\r
+ int pitch = gpVesaCurMode->pitch;\r
+ int bytes_per_px = (gpVesaCurMode->bpp + 7) / 8;\r
+ int x = giVesaCursorX*giVT_CharWidth;\r
+ int y = giVesaCursorY*giVT_CharHeight;\r
+ int i;\r
+ Uint8 *fb = (void*)gpVesa_Framebuffer;\r
+ \r
+ //Debug("Cursor flip");\r
+ \r
+ // Sanity check\r
+ if(giVesaCursorX < 0 || giVesaCursorY < 0\r
+ || y*pitch + x + (giVT_CharHeight-1)*pitch > (int)gpVesaCurMode->fbSize) {\r
+ Log_Notice("VESA", "Cursor OOB (%i,%i)", x, y);\r
+ giVesaCursorTimer = -1;\r
+ return;\r
+ }\r
+ \r
+ // Draw cursor\r
+ fb += (y+1)*pitch + x*bytes_per_px;\r
+ \r
+ switch(bytes_per_px)\r
+ {\r
+ case 1:\r
+ for( i = 1; i < giVT_CharHeight-1; i++, fb += pitch )\r
+ *fb = ~*fb;\r
+ break;\r
+ case 2:\r
+ for( i = 1; i < giVT_CharHeight-1; i++, fb += pitch ) {\r
+ fb[0] = ~fb[0];\r
+ fb[1] = ~fb[1];\r
+ }\r
+ break;\r
+ case 3:\r
+ for( i = 1; i < giVT_CharHeight-1; i++, fb += pitch ) {\r
+ fb[0] = ~fb[0];\r
+ fb[1] = ~fb[1];\r
+ fb[2] = ~fb[2];\r
+ }\r
+ break;\r
+ case 4:\r
+ for( i = 1; i < giVT_CharHeight-1; i++, fb += pitch ) {\r
+ fb[0] = ~fb[0];\r
+ fb[1] = ~fb[1];\r
+ fb[2] = ~fb[2];\r
+ fb[3] = ~fb[3];\r
+ }\r
+ break;\r
+ default:\r
+ Log_Error("VESA", "Vesa_FlipCursor - Bug Report, unknown bytes_per_px (%i)", bytes_per_px);\r
+ giVesaCursorTimer = -1;\r
+ return ;\r
+ }\r
+ \r
+ #if BLINKING_CURSOR\r
+ giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Arg);\r
+ #endif\r
+}\r
+\r
+// ------------------------\r
+// --- 2D Accelleration ---\r
+// ------------------------\r
+void Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)\r
+{\r
+ // TODO: Handle non-32bit modes\r
+ int pitch = gpVesaCurMode->pitch/4;\r
+ Uint32 *buf = (Uint32*)gpVesa_Framebuffer + Y*pitch + X;\r
+ while( H -- ) {\r
+ memsetd(buf, Colour, W);\r
+ buf += pitch;\r
+ }\r
+}\r
+\r
+void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)\r
+{\r
+ int scrnpitch = gpVesaCurMode->pitch;\r
+ int bytes_per_px = (gpVesaCurMode->bpp + 7) / 8;\r
+ int dst = DstY*scrnpitch + DstX;\r
+ int src = SrcY*scrnpitch + SrcX;\r
+ int tmp;\r
+ \r
+ //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",\r
+ // Ent, DstX, DstY, SrcX, SrcY, W, H);\r
+ \r
+ if(SrcX + W > gpVesaCurMode->width)\r
+ W = gpVesaCurMode->width - SrcX;\r
+ if(DstX + W > gpVesaCurMode->width)\r
+ W = gpVesaCurMode->width - DstX;\r
+ if(SrcY + H > gpVesaCurMode->height)\r
+ H = gpVesaCurMode->height - SrcY;\r
+ if(DstY + H > gpVesaCurMode->height)\r
+ H = gpVesaCurMode->height - DstY;\r
+ \r
+ //Debug("W = %i, H = %i", W, H);\r
+ \r
+ if( dst > src ) {\r
+ // Reverse copy\r
+ dst += H*scrnpitch;\r
+ src += H*scrnpitch;\r
+ while( H -- ) {\r
+ dst -= scrnpitch;\r
+ src -= scrnpitch;\r
+ tmp = W*bytes_per_px;\r
+ for( tmp = W; tmp --; ) {\r
+ *(Uint8*)(gpVesa_Framebuffer + dst + tmp) = *(Uint8*)(gpVesa_Framebuffer + src + tmp);\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ // Normal copy is OK\r
+ while( H -- ) {\r
+ memcpy((void*)gpVesa_Framebuffer + dst, (void*)gpVesa_Framebuffer + src, W*bytes_per_px);\r
+ dst += scrnpitch;\r
+ src += scrnpitch;\r
+ }\r
+ }\r
+ //Log("Vesa_2D_Blit: RETURN");\r
+}\r