6 #define VERSION ((0<<8)|10)
11 #include <tpl_drv_video.h>
15 int Video_Install(char **Arguments);
16 Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
17 Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
18 int Video_IOCtl(tVFS_Node *Node, int ID, void *Data);
19 // --- 2D Acceleration Functions --
20 void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
21 void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
24 //MODULE_DEFINE(0, VERSION, NativeVideo, Video_Install, NULL, NULL);
25 tDevFS_Driver gVideo_DriverStruct = {
34 int giVideo_CurrentFormat;
35 // --- 2D Video Stream Handlers ---
36 tDrvUtil_Video_2DHandlers gVideo_2DFunctions = {
43 int Video_Install(char **Arguments)
46 giVideo_DriverID = DevFS_AddDevice( &gVideo_DriverStruct );
47 if(giVideo_DriverID == -1)
48 return MODULE_ERR_MISC;
54 * \brief Read from framebuffer (unimplemented)
56 Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
62 * \brief Write to the framebuffer
64 Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
67 ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
74 switch( giVideo_CurrentFormat )
76 case VIDEO_BUFFMT_TEXT:
78 tVT_Char *chars = Buffer;
79 // int pitch = giUI_Pitch;
80 int widthInChars = giUI_Width/giVT_CharWidth;
81 int heightInChars = giUI_Height/giVT_CharHeight;
83 Uint32 tmpBuf[giVT_CharHeight*giVT_CharWidth];
85 Length /= sizeof(tVT_Char);
86 Offset /= sizeof(tVT_Char);
88 x = Offset % widthInChars;
89 y = Offset / widthInChars;
92 if( Offset > (Uint64)(heightInChars*widthInChars) ) {
96 if(y >= heightInChars) {
101 // Clip to screen size
102 if( (int)Offset + (int)Length > heightInChars*widthInChars ) {
103 Log_Debug("Video", "%i + %i > %i*%i (%i)",
104 (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars);
105 Length = heightInChars*widthInChars - Offset;
106 Log_Notice("Video", "Clipping write size to %i characters", (int)Length);
110 for( i = 0; i < (int)Length; i++ )
114 //dest + x*giVT_CharWidth, pitch,
115 tmpBuf, giVT_CharWidth,
116 VT_Colour12to24(chars->BGCol),
117 VT_Colour12to24(chars->FGCol)
120 x*giVT_CharWidth, y*giVT_CharHeight,
121 giVT_CharWidth, giVT_CharHeight,
127 if( x >= widthInChars ) {
130 //dest += pitch*giVT_CharHeight;
133 Length *= sizeof(tVT_Char);
137 case VIDEO_BUFFMT_FRAMEBUFFER:
141 if(giUI_Pitch*giUI_Height < Offset+Length)
143 Log_Warning("Video", "Video_Write - Framebuffer Overflow");
148 LOG("buffer = %p", Buffer);
149 LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length);
151 startX = Offset % giUI_Width;
152 startY = Offset / giUI_Width;
154 if( Length + startX < giUI_Width )
164 // First scanline (partial or full)
167 giUI_Width - startX, 1,
170 Length -= giUI_Width - startX;
171 Buffer += giUI_Width - startX;
174 for( i = 0; i < Length / giUI_Height; i ++ )
180 Buffer += giUI_Width;
183 // Final scanline (partial)
184 if( Length % giUI_Height )
188 Length % giUI_Height, 1,
195 case VIDEO_BUFFMT_2DSTREAM:
196 Length = DrvUtil_Video_2DStream(
197 NULL, // Single framebuffer, so Ent is unused
198 Buffer, Length, &gVideo_2DFunctions, sizeof(gVideo_2DFunctions)
207 // Tell the UI to blit
214 const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
216 * \brief Handle messages to the device
218 int Video_IOCtl(tVFS_Node *Node, int ID, void *Data)
221 tVideo_IOCtl_Mode *mode = Data;
224 BASE_IOCTLS(DRV_TYPE_VIDEO, "NativeVideo", VERSION, csaVIDEO_IOCTLS);
226 // Video mode control
227 // - We cheat, and only have one mode
228 case VIDEO_IOCTL_GETSETMODE:
230 case VIDEO_IOCTL_FINDMODE:
231 case VIDEO_IOCTL_MODEINFO:
233 mode->width = giUI_Width;
234 mode->height = giUI_Height;
240 case VIDEO_IOCTL_SETBUFFORMAT:
241 ret = giVideo_CurrentFormat;
243 giVideo_CurrentFormat = *(int*)Data;
248 case VIDEO_IOCTL_SETCURSOR: // Set cursor position
250 if(giVesaCursorX > 0)
251 Vesa_FlipCursor(Node);
253 giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x;
254 giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y;
255 //Log_Debug("VESA", "Cursor position (%i,%i)", giVesaCursorX, giVesaCursorY);
257 giVesaCursorX < 0 || giVesaCursorY < 0
258 || giVesaCursorX >= gpVesaCurMode->width/giVT_CharWidth
259 || giVesaCursorY >= gpVesaCurMode->height/giVT_CharHeight)
262 if(giVesaCursorTimer != -1) {
263 Time_RemoveTimer(giVesaCursorTimer);
264 giVesaCursorTimer = -1;
272 // Log_Debug("VESA", "Updating timer %i?", giVesaCursorTimer);
273 if(giVesaCursorTimer == -1)
274 giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node);
276 Vesa_FlipCursor(Node);
279 //Log_Debug("VESA", "Cursor position (%i,%i) Timer %i", giVesaCursorX, giVesaCursorY, giVesaCursorTimer);
283 case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer
289 // --- 2D Acceleration Functions --
290 void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
292 UI_FillBitmap(X, Y, W, H, Colour);
295 void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
297 UI_BlitFramebuffer(DstX, DstY, SrcX, SrcY, W, H);