3 * Common Driver/Filesystem Helper Functions
7 #include <api_drv_disk.h>
8 #include <api_drv_video.h>
13 //int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);
14 //size_t DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Src);
15 void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
16 void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
19 tDrvUtil_Video_2DHandlers gDrvUtil_Stub_2DFunctions = {
21 DrvUtil_Video_2D_Fill,
26 // --- Video Driver Helpers ---
27 int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
28 tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
30 void *stream = Buffer;
37 stream = (void*)((tVAddr)stream + 1);
39 if(op > NUM_VIDEO_2DOPS) {
40 Log_Warning("DrvUtil",
41 "DrvUtil_Video_2DStream: Unknown operation %i",
46 if(op*sizeof(void*) > SizeofHandlers) {
47 Log_Warning("DrvUtil",
48 "DrvUtil_Video_2DStream: Driver does not support op %i",
55 case VIDEO_2DOP_NOP: break;
58 if(rem < 12) return Length-rem;
61 Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
62 " does not support VIDEO_2DOP_FILL");
68 ((Uint16*)stream)[0], ((Uint16*)stream)[1],
69 ((Uint16*)stream)[2], ((Uint16*)stream)[3],
74 stream = (void*)((tVAddr)stream + 12);
78 if(rem < 12) return Length-rem;
81 Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
82 " does not support VIDEO_2DOP_BLIT");
88 ((Uint16*)stream)[0], ((Uint16*)stream)[1],
89 ((Uint16*)stream)[2], ((Uint16*)stream)[3],
90 ((Uint16*)stream)[4], ((Uint16*)stream)[5]
94 stream = (void*)((tVAddr)stream + 12);
102 int DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Buffer)
105 ENTER("iMode pFBInfo xOffset xLength pBuffer",
106 Mode, FBInfo, Offset, Length, Buffer);
109 case VIDEO_BUFFMT_TEXT:
111 tVT_Char *chars = Buffer;
112 int bytes_per_px = FBInfo->Depth / 8;
113 int widthInChars = FBInfo->Width/giVT_CharWidth;
114 int heightInChars = FBInfo->Height/giVT_CharHeight;
117 Length /= sizeof(tVT_Char); Offset /= sizeof(tVT_Char);
119 x = Offset % widthInChars; y = Offset / widthInChars;
122 if(Offset > heightInChars * widthInChars) LEAVE_RET('i', 0);
123 if(y >= heightInChars) LEAVE_RET('i', 0);
125 if( Offset + Length > heightInChars*widthInChars )
127 Length = heightInChars*widthInChars - Offset;
130 dest = FBInfo->Framebuffer;
131 dest += y * giVT_CharHeight * FBInfo->Pitch;
133 for( i = 0; i < Length; i++ )
135 if( y >= heightInChars )
137 Log_Notice("DrvUtil", "Stopped at %i", i);
143 dest + x*giVT_CharWidth*bytes_per_px, FBInfo->Depth, FBInfo->Pitch,
144 VT_Colour12toN(chars->BGCol, FBInfo->Depth),
145 VT_Colour12toN(chars->FGCol, FBInfo->Depth)
150 if( x >= widthInChars )
154 dest += FBInfo->Pitch*giVT_CharHeight;
157 Length = i * sizeof(tVT_Char);
161 case VIDEO_BUFFMT_FRAMEBUFFER:
162 if(FBInfo->Width*FBInfo->Height*4 < Offset+Length)
164 Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Framebuffer Overflow");
168 //TODO: Handle non 32-bpp framebuffer modes
169 if( FBInfo->Depth != 32 ) {
170 Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Don't support non 32-bpp FB mode");
175 //TODO: Handle pitch != Width*BytesPerPixel
176 // Copy to Frambuffer
177 dest = (Uint8 *)FBInfo->Framebuffer + Offset;
178 memcpy(dest, Buffer, Length);
181 case VIDEO_BUFFMT_2DSTREAM:
182 Length = DrvUtil_Video_2DStream(
183 FBInfo, Buffer, Length,
184 &gDrvUtil_Stub_2DFunctions, sizeof(gDrvUtil_Stub_2DFunctions)
196 void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
198 tDrvUtil_Video_BufInfo *FBInfo = Ent;
200 // TODO: Handle non-32bit modes
201 if( FBInfo->Depth != 32 ) return;
203 // TODO: Be less hacky
204 int pitch = FBInfo->Pitch/4;
205 Uint32 *buf = (Uint32*)FBInfo->Framebuffer + Y*pitch + X;
210 for(i=W;i--;tmp++) *tmp = Colour;
215 void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
217 tDrvUtil_Video_BufInfo *FBInfo = Ent;
218 int scrnpitch = FBInfo->Pitch;
219 int bytes_per_px = (FBInfo->Depth + 7) / 8;
220 int dst = DstY*scrnpitch + DstX;
221 int src = SrcY*scrnpitch + SrcX;
224 //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",
225 // Ent, DstX, DstY, SrcX, SrcY, W, H);
227 if(SrcX + W > FBInfo->Width) W = FBInfo->Width - SrcX;
228 if(DstX + W > FBInfo->Width) W = FBInfo->Width - DstX;
229 if(SrcY + H > FBInfo->Height) H = FBInfo->Height - SrcY;
230 if(DstY + H > FBInfo->Height) H = FBInfo->Height - DstY;
232 //Debug("W = %i, H = %i", W, H);
241 tmp = W*bytes_per_px;
242 for( tmp = W; tmp --; ) {
243 *((Uint8*)FBInfo->Framebuffer + dst + tmp) = *((Uint8*)FBInfo->Framebuffer + src + tmp);
250 memcpy((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, W*bytes_per_px);
255 //Log("Vesa_2D_Blit: RETURN");
259 // --- Disk Driver Helpers ---
260 Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
261 tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
263 Uint8 tmp[BlockSize]; // C99
264 Uint64 block = Start / BlockSize;
265 int offset = Start - block * BlockSize;
266 int leading = BlockSize - offset;
271 ENTER("XStart XLength pBuffer pReadBlocks XBlockSize xArgument",
272 Start, Length, Buffer, ReadBlocks, BlockSize, Argument);
274 // Non aligned start, let's fix that!
277 if(leading > Length) leading = Length;
278 LOG("Reading %i bytes from Block1+%i", leading, offset);
279 ret = ReadBlocks(block, 1, tmp, Argument);
284 memcpy( Buffer, &tmp[offset], leading );
286 if(leading == Length) {
291 Buffer = (Uint8*)Buffer + leading;
293 num = ( Length - leading ) / BlockSize;
294 tailings = Length - num * BlockSize - leading;
297 num = Length / BlockSize;
298 tailings = Length % BlockSize;
301 // Read central blocks
304 LOG("Reading %i blocks", num);
305 ret = ReadBlocks(block, num, Buffer, Argument);
307 LEAVE('X', leading + ret * BlockSize);
308 return leading + ret * BlockSize;
312 // Read last tailing block
315 LOG("Reading %i bytes from last block", tailings);
317 Buffer = (Uint8*)Buffer + num * BlockSize;
318 ret = ReadBlocks(block, 1, tmp, Argument);
320 LEAVE('X', leading + num * BlockSize);
321 return leading + num * BlockSize;
323 memcpy( Buffer, tmp, tailings );
330 Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer,
331 tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks,
332 Uint64 BlockSize, Uint Argument)
334 Uint8 tmp[BlockSize]; // C99
335 Uint64 block = Start / BlockSize;
336 int offset = Start - block * BlockSize;
337 int leading = BlockSize - offset;
342 ENTER("XStart XLength pBuffer pReadBlocks pWriteBlocks XBlockSize xArgument",
343 Start, Length, Buffer, ReadBlocks, WriteBlocks, BlockSize, Argument);
345 // Non aligned start, let's fix that!
348 if(leading > Length) leading = Length;
349 LOG("Writing %i bytes to Block1+%i", leading, offset);
350 // Read a copy of the block
351 ret = ReadBlocks(block, 1, tmp, Argument);
357 memcpy( &tmp[offset], Buffer, leading );
359 ret = WriteBlocks(block, 1, tmp, Argument);
365 if(leading == Length) {
370 Buffer = (Uint8*)Buffer + leading;
372 num = ( Length - leading ) / BlockSize;
373 tailings = Length - num * BlockSize - leading;
376 num = Length / BlockSize;
377 tailings = Length % BlockSize;
380 // Read central blocks
383 LOG("Writing %i blocks", num);
384 ret = WriteBlocks(block, num, Buffer, Argument);
386 LEAVE('X', leading + ret * BlockSize);
387 return leading + ret * BlockSize;
391 // Read last tailing block
394 LOG("Writing %i bytes to last block", tailings);
396 Buffer = (Uint8*)Buffer + num * BlockSize;
398 ret = ReadBlocks(block, 1, tmp, Argument);
400 LEAVE('X', leading + num * BlockSize);
401 return leading + num * BlockSize;
404 memcpy( tmp, Buffer, tailings );
406 ret = WriteBlocks(block, 1, tmp, Argument);
408 LEAVE('X', leading + num * BlockSize);
409 return leading + num * BlockSize;