X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrvutil.c;h=d19a050464806f72a58eb638a90e04a509d3893c;hb=cbe0cc999c61fff862054bf428b7163e5458f2af;hp=00bfb78e813d37e120f0277c783c095676f571ea;hpb=7ecc6d0f1754b944e13b117830df504404b5859e;p=tpg%2Facess2.git diff --git a/Kernel/drvutil.c b/Kernel/drvutil.c index 00bfb78e..d19a0504 100644 --- a/Kernel/drvutil.c +++ b/Kernel/drvutil.c @@ -28,20 +28,42 @@ tDrvUtil_Video_2DHandlers gDrvUtil_Stub_2DFunctions = { 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", @@ -62,7 +84,7 @@ int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, 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" @@ -72,13 +94,13 @@ int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, 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: @@ -92,13 +114,13 @@ int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, 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; } @@ -106,20 +128,29 @@ int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, 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); @@ -179,17 +210,58 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t 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: @@ -203,11 +275,14 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t 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; @@ -221,7 +296,8 @@ void DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *B free( Buf->CursorSaveBuf ); Buf->CursorSaveBuf = NULL; } - free(Buf->CursorBitmap); + if( Buf->CursorBitmap != &gDrvUtil_TextModeCursor) + free(Buf->CursorBitmap); Buf->CursorBitmap = NULL; } @@ -230,31 +306,45 @@ void DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *B { 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 ; } @@ -314,17 +404,47 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf) (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 } @@ -333,7 +453,8 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf) } 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; } } @@ -348,6 +469,8 @@ void DrvUtil_Video_RemoveCursor(tDrvUtil_Video_BufInfo *Buf) 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; @@ -416,6 +539,9 @@ void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uin } } } + 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 -- ) { @@ -430,7 +556,7 @@ void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uin // --- 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; @@ -499,8 +625,8 @@ Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, 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