6 #define VERSION ((0<<8)|10)
12 #include <api_drv_video.h>
16 int Video_Install(char **Arguments);
17 size_t Video_Read(tVFS_Node *Node, Uint64 Offset, size_t Length, void *Buffer, Uint Flags);
18 size_t Video_Write(tVFS_Node *Node, Uint64 Offset, size_t Length, const void *Buffer, Uint Flags);
19 int Video_IOCtl(tVFS_Node *Node, int ID, void *Data);
20 // --- 2D Acceleration Functions --
21 void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
22 void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
25 //MODULE_DEFINE(0, VERSION, NativeVideo, Video_Install, NULL, NULL);
26 tVFS_NodeType gVideo_NodeType = {
31 tDevFS_Driver gVideo_DriverStruct = {
34 .Type = &gVideo_NodeType
38 int giVideo_CurrentFormat;
39 // --- 2D Video Stream Handlers ---
40 tDrvUtil_Video_2DHandlers gVideo_2DFunctions = {
47 int Video_Install(char **Arguments)
50 giVideo_DriverID = DevFS_AddDevice( &gVideo_DriverStruct );
51 if(giVideo_DriverID == -1)
52 return MODULE_ERR_MISC;
58 * \brief Read from framebuffer (unimplemented)
60 size_t Video_Read(tVFS_Node *Node, Uint64 Offset, size_t Length, void *Buffer, Uint Flags)
66 * \brief Write to the framebuffer
68 size_t Video_Write(tVFS_Node *Node, Uint64 Offset, size_t Length, const void *Buffer, Uint Flags)
71 ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
78 switch( giVideo_CurrentFormat )
80 case VIDEO_BUFFMT_TEXT:
82 const tVT_Char *chars = Buffer;
83 // int pitch = giUI_Pitch;
84 int widthInChars = giUI_Width/giVT_CharWidth;
85 int heightInChars = giUI_Height/giVT_CharHeight;
87 Uint32 tmpBuf[giVT_CharHeight*giVT_CharWidth];
89 Length /= sizeof(tVT_Char);
90 Offset /= sizeof(tVT_Char);
92 x = Offset % widthInChars;
93 y = Offset / widthInChars;
96 if( Offset > (Uint64)(heightInChars*widthInChars) ) {
97 Log_Notice("Video", "Offset (%i) > %i*%i (%i)", Offset,
98 heightInChars, widthInChars, heightInChars*widthInChars);
102 if(y >= heightInChars) {
107 // Clip to screen size
108 if( (int)Offset + (int)Length > heightInChars*widthInChars ) {
109 Log_Debug("Video", "%i + %i > %i*%i (%i)",
110 (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars);
111 Length = heightInChars*widthInChars - Offset;
112 Log_Notice("Video", "Clipping write size to %i characters", (int)Length);
115 // Log_Debug("Video", "(%i,%i) %i chars", x, y, (int)Length);
118 for( i = 0; i < (int)Length; i++ )
122 // Log_Debug("Video", "Render Char 0x%x in 0x%03x:%03x",
123 // chars->Ch, chars->FGCol, chars->BGCol);
124 memset(tmpBuf, 0xFF, giVT_CharWidth*giVT_CharHeight*4);
127 tmpBuf, 32, giVT_CharWidth*4,
128 VT_Colour12to24(chars->BGCol),
129 VT_Colour12to24(chars->FGCol)
132 x*giVT_CharWidth, y*giVT_CharHeight,
133 giVT_CharWidth, giVT_CharHeight,
140 x*giVT_CharWidth, y*giVT_CharHeight,
141 giVT_CharWidth, giVT_CharHeight,
142 VT_Colour12to24(chars->BGCol)
148 if( x >= widthInChars ) {
151 //dest += pitch*giVT_CharHeight;
154 Length *= sizeof(tVT_Char);
158 case VIDEO_BUFFMT_FRAMEBUFFER:
162 if(giUI_Pitch*giUI_Height < Offset+Length)
164 Log_Warning("Video", "Video_Write - Framebuffer Overflow");
169 LOG("buffer = %p", Buffer);
172 startX = Offset % giUI_Width;
173 startY = Offset / giUI_Width;
176 if( startX + Length < giUI_Width )
184 else if( startX == 0 )
186 int lines = Length / giUI_Width;
187 int rem = Length % giUI_Width;
188 UI_BlitBitmap(0, startY, giUI_Width, lines, Buffer);
190 UI_BlitBitmap(0, startY + lines, rem, 1, (Uint32*)Buffer + lines*giUI_Width);
195 // First scanline (partial or full)
198 giUI_Width - startX, 1,
201 Length -= giUI_Width - startX;
202 Buffer += giUI_Width - startX;
205 for( i = 0; i < Length / giUI_Height; i ++ )
211 Buffer += giUI_Width;
214 // Final scanline (partial)
215 if( Length % giUI_Height )
219 Length % giUI_Height, 1,
226 case VIDEO_BUFFMT_2DSTREAM:
227 Length = DrvUtil_Video_2DStream(
228 NULL, // Single framebuffer, so Ent is unused
229 Buffer, Length, &gVideo_2DFunctions, sizeof(gVideo_2DFunctions)
238 // Tell the UI to blit
245 const char * csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
247 * \brief Handle messages to the device
249 int Video_IOCtl(tVFS_Node *Node, int ID, void *Data)
252 tVideo_IOCtl_Mode *mode = Data;
255 BASE_IOCTLS(DRV_TYPE_VIDEO, "NativeVideo", VERSION, csaVIDEO_IOCTLS);
257 // Video mode control
258 // - We cheat, and only have one mode
259 case VIDEO_IOCTL_GETSETMODE:
260 // - Abuse GETSETMODE to update size
261 Node->Size = giUI_Pitch * giUI_Height;
263 case VIDEO_IOCTL_FINDMODE:
264 case VIDEO_IOCTL_MODEINFO:
266 mode->width = giUI_Width;
267 mode->height = giUI_Height;
273 case VIDEO_IOCTL_SETBUFFORMAT:
274 ret = giVideo_CurrentFormat;
276 giVideo_CurrentFormat = *(int*)Data;
281 case VIDEO_IOCTL_SETCURSOR: // Set cursor position
283 if(giVideo_CursorX > 0)
284 Video_FlipCursor(Node);
286 giVideo_CursorX = ((tVideo_IOCtl_Pos*)Data)->x;
287 giVideo_CursorY = ((tVideo_IOCtl_Pos*)Data)->y;
288 if( giVideo_CursorX < 0 || giVesaCursorY < 0
289 || giVideo_CursorX >= gpVesaCurMode->width/giVT_CharWidth
290 || giVideo_CursorY >= gpVesaCurMode->height/giVT_CharHeight)
293 if(giVesaCursorTimer != -1) {
294 Time_RemoveTimer(giVesaCursorTimer);
295 giVesaCursorTimer = -1;
303 // Log_Debug("VESA", "Updating timer %i?", giVesaCursorTimer);
304 if(giVesaCursorTimer == -1)
305 giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node);
307 Vesa_FlipCursor(Node);
310 //Log_Debug("VESA", "Cursor position (%i,%i) Timer %i", giVesaCursorX, giVesaCursorY, giVesaCursorTimer);
317 // --- 2D Acceleration Functions --
318 void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
320 UI_FillBitmap(X, Y, W, H, Colour);
323 void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
325 UI_BlitFramebuffer(DstX, DstY, SrcX, SrcY, W, H);