DrvUtil_Video_2D_Fill,
DrvUtil_Video_2D_Blit
};
+tVideo_IOCtl_Bitmap gDrvUtil_TextModeCursor = {
+ 8, 16,
+ 0, 0,
+ {
+ 0, 0, 0 , 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0,-1, 0xFF000000, 0, 0, 0, 0, 0,
+ 0, 0, 0 , 0, 0, 0, 0, 0,
+ 0, 0, 0 , 0, 0, 0, 0, 0
+ }
+};
// === CODE ===
// --- Video Driver Helpers ---
-int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
+int DrvUtil_Video_2DStream(void *Ent, const void *Buffer, int Length,
tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
{
- void *stream = Buffer;
+ const Uint8 *stream = Buffer;
int rem = Length;
int op;
while( rem )
{
rem --;
- op = *(Uint8*)stream;
- stream = (void*)((tVAddr)stream + 1);
+ op = *stream;
+ stream ++;
if(op > NUM_VIDEO_2DOPS) {
Log_Warning("DrvUtil",
case VIDEO_2DOP_NOP: break;
case VIDEO_2DOP_FILL:
- if(rem < 12) return Length-rem;
+ if(rem < 10) return Length-rem;
if(!Handlers->Fill) {
Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
Handlers->Fill(
Ent,
- ((Uint16*)stream)[0], ((Uint16*)stream)[1],
- ((Uint16*)stream)[2], ((Uint16*)stream)[3],
- ((Uint32*)stream)[2]
+ ((const Uint16*)stream)[0], ((const Uint16*)stream)[1],
+ ((const Uint16*)stream)[2], ((const Uint16*)stream)[3],
+ ((const Uint32*)stream)[4]
);
- rem -= 12;
- stream = (void*)((tVAddr)stream + 12);
+ rem -= 10;
+ stream += 10;
break;
case VIDEO_2DOP_BLIT:
Handlers->Blit(
Ent,
- ((Uint16*)stream)[0], ((Uint16*)stream)[1],
- ((Uint16*)stream)[2], ((Uint16*)stream)[3],
- ((Uint16*)stream)[4], ((Uint16*)stream)[5]
+ ((const Uint16*)stream)[0], ((const Uint16*)stream)[1],
+ ((const Uint16*)stream)[2], ((const Uint16*)stream)[3],
+ ((const Uint16*)stream)[4], ((const Uint16*)stream)[5]
);
rem -= 12;
- stream = (void*)((tVAddr)stream + 12);
+ stream += 12;
break;
}
return 0;
}
-int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Buffer)
+int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, const void *Buffer)
{
Uint8 *dest;
+ const Uint32 *src = Buffer;
+ int csr_x, csr_y;
+ int x, y;
+ int bytes_per_px = (FBInfo->Depth + 7) / 8;
ENTER("pFBInfo xOffset xLength pBuffer",
Mode, FBInfo, Offset, Length, Buffer);
+
+ csr_x = FBInfo->CursorX;
+ csr_y = FBInfo->CursorY;
+
+ DrvUtil_Video_RemoveCursor(FBInfo);
+
switch( FBInfo->BufferFormat )
{
case VIDEO_BUFFMT_TEXT:
{
- tVT_Char *chars = Buffer;
- int bytes_per_px = (FBInfo->Depth + 7) / 8;
+ const tVT_Char *chars = Buffer;
int widthInChars = FBInfo->Width/giVT_CharWidth;
int heightInChars = FBInfo->Height/giVT_CharHeight;
- int x, y, i;
+ int i;
LOG("bytes_per_px = %i", bytes_per_px);
LOG("widthInChars = %i, heightInChars = %i", widthInChars, heightInChars);
return 0;
}
- //TODO: Handle non 32-bpp framebuffer modes
- if( FBInfo->Depth != 32 ) {
- Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Don't support non 32-bpp FB mode");
- return 0;
- }
+ switch(FBInfo->Depth)
+ {
+ case 15:
+ case 16:
+ Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in LFB write");
+ break;
+ case 24:
+ x = Offset % FBInfo->Width;
+ y = Offset / FBInfo->Width;
+ dest = (Uint8*)FBInfo->Framebuffer + y*FBInfo->Pitch;
+ for( ; Length >= 4; Length -= 4 )
+ {
+ dest[x*3+0] = *src & 0xFF;
+ dest[x*3+1] = (*src >> 8) & 0xFF;
+ dest[x*3+2] = (*src >> 16) & 0xFF;
+ x ++;
+ if(x == FBInfo->Width) {
+ dest += FBInfo->Pitch;
+ x = 0;
+ }
+ }
+ break;
+ case 32:
+ // Copy to Frambuffer
+ if( FBInfo->Pitch != FBInfo->Width*4 )
+ {
+ Uint32 *px;
+ // Pitch isn't 4*Width
+ x = Offset % FBInfo->Width;
+ y = Offset / FBInfo->Height;
+
+ px = (Uint32*)FBInfo->Framebuffer + y*FBInfo->Pitch/4;
-
- //TODO: Handle pitch != Width*BytesPerPixel
- // Copy to Frambuffer
- dest = (Uint8 *)FBInfo->Framebuffer + Offset;
- memcpy(dest, Buffer, Length);
+ for( ; Length >= 4; Length -= 4, x )
+ {
+ px[x++] = *src ++;
+ if( x == FBInfo->Width ) {
+ x = 0;
+ px += FBInfo->Pitch;
+ }
+ }
+ }
+ else
+ {
+ dest = (Uint8 *)FBInfo->Framebuffer + Offset;
+ memcpy(dest, Buffer, Length);
+ }
+ break;
+ default:
+ Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Unknown bit depthn %i", FBInfo->Depth);
+ break;
+ }
break;
case VIDEO_BUFFMT_2DSTREAM:
LEAVE('i', -1);
return -1;
}
+
+ DrvUtil_Video_DrawCursor(FBInfo, csr_x, csr_y);
+
LEAVE('x', Length);
return Length;
}
-void DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bitmap)
+int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bitmap)
{
int csrX = Buf->CursorX, csrY = Buf->CursorY;
size_t size;
free( Buf->CursorSaveBuf );
Buf->CursorSaveBuf = NULL;
}
- free(Buf->CursorBitmap);
+ if( Buf->CursorBitmap != &gDrvUtil_TextModeCursor)
+ free(Buf->CursorBitmap);
Buf->CursorBitmap = NULL;
}
{
Buf->CursorX = -1;
Buf->CursorY = -1;
- return ;
+ return 0;
}
- // Check the new bitmap is valid
- size = sizeof(tVideo_IOCtl_Bitmap) + Bitmap->W*Bitmap->H*4;
- if( !CheckMem(Bitmap, size) ) {
+ // Sanity check the bitmap
+ if( !CheckMem(Bitmap, sizeof(*Bitmap)) || !CheckMem(Bitmap->Data, Bitmap->W*Bitmap->H*sizeof(Uint32)) )
+ {
Log_Warning("DrvUtil", "DrvUtil_Video_SetCursor: Bitmap (%p) is in invalid memory", Bitmap);
- return;
+ errno = -EINVAL;
+ return -1;
+ }
+
+ // Don't take a copy of the DrvUtil provided cursor
+ if( Bitmap == &gDrvUtil_TextModeCursor )
+ {
+ Buf->CursorBitmap = Bitmap;
+ }
+ else
+ {
+ size = sizeof(tVideo_IOCtl_Bitmap) + Bitmap->W*Bitmap->H*4;
+
+ // Take a copy
+ Buf->CursorBitmap = malloc( size );
+ memcpy(Buf->CursorBitmap, Bitmap, size);
}
-
- // Take a copy
- Buf->CursorBitmap = malloc( size );
- memcpy(Buf->CursorBitmap, Bitmap, size);
// Restore cursor position
DrvUtil_Video_DrawCursor(Buf, csrX, csrY);
+ return 0;
}
void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
{
int render_ox=0, render_oy=0, render_w, render_h;
+ DrvUtil_Video_RemoveCursor(Buf);
+
// X < 0 disables the cursor
if( X < 0 ) {
- Render->CursorX = -1;
+ Buf->CursorX = -1;
return ;
}
(Uint8*)dest + y*Buf->Pitch,
render_w*bytes_per_px
);
+
// Draw the cursor
switch(Buf->Depth)
{
+ case 15:
+ case 16:
+ Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in cursor draw");
+ break;
+ case 24:
+ for( y = 0; y < render_h; y ++ )
+ {
+ Uint8 *px;
+ px = dest;
+ for(x = 0; x < render_w; x ++, px += 3)
+ {
+ Uint32 value = src[x];
+ // TODO: Should I implement alpha blending?
+ if(value & 0xFF000000)
+ {
+ px[0] = value & 0xFF;
+ px[1] = (value >> 8) & 0xFF;
+ px[2] = (value >> 16) & 0xFF;
+ }
+ else
+ ;
+ }
+ src += Buf->CursorBitmap->W;
+ dest = (Uint8*)dest + Buf->Pitch;
+ }
+ break;
case 32:
for( y = 0; y < render_h; y ++ )
{
- for(x = 0; x < render_w; x ++ )
+ Uint32 *px;
+ px = dest;
+ for(x = 0; x < render_w; x ++, px ++)
{
+ Uint32 value = src[x];
// TODO: Should I implement alpha blending?
- if(src[x] & 0xFF000000)
- ((Uint32*)dest)[x] = src[x];
+ if(value & 0xFF000000)
+ *px = value;
else
; // NOP, completely transparent
}
}
break;
default:
- Log_Error("DrvUtil", "TODO: Implement non 32-bpp cursor");
+ Log_Error("DrvUtil", "RenderCursor - Unknown bit depth %i", Buf->Depth);
+ Buf->CursorX = -1;
break;
}
}
if( !Buf->CursorBitmap || Buf->CursorX == -1 ) return ;
if( !Buf->CursorSaveBuf ) return ;
+// Debug("DrvUtil_Video_RemoveCursor: (Buf=%p) dest_x=%i, dest_y=%i", Buf, Buf->CursorDestX, Buf->CursorDestY);
+
// Set up
save_pitch = Buf->CursorBitmap->W * bytes_per_px;
dest = (Uint8*)Buf->Framebuffer + Buf->CursorDestY * Buf->Pitch + Buf->CursorDestX*bytes_per_px;
}
}
}
+ else if(W == FBInfo->Width && FBInfo->Pitch == FBInfo->Width*bytes_per_px) {
+ memmove((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, H*FBInfo->Pitch);
+ }
else {
// Normal copy is OK
while( H -- ) {
// --- Disk Driver Helpers ---
Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
- tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
+ tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
{
Uint8 tmp[BlockSize]; // C99
Uint64 block = Start / BlockSize;
return Length;
}
-Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer,
- tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks,
+Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer,
+ tDrvUtil_Read_Callback ReadBlocks, tDrvUtil_Write_Callback WriteBlocks,
Uint64 BlockSize, Uint Argument)
{
Uint8 tmp[BlockSize]; // C99