BuildConf/host - Slight fix to allow scan-build for non 64-bit architectures
[tpg/acess2.git] / Kernel / drvutil.c
index 8847ae2..00ab5ce 100644 (file)
@@ -32,22 +32,22 @@ tVideo_IOCtl_Bitmap gDrvUtil_TextModeCursor = {
        8, 16,
        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,
-               -1, 0xFF000000, 0, 0, 0, 0, 0, 0,
-                0, 0         , 0, 0, 0, 0, 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
        }
 };
 
@@ -131,17 +131,26 @@ int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
 int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Buffer)
 {
        Uint8   *dest;
+       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;
                 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);
@@ -201,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;
-               }       
-
-               
-               //TODO: Handle pitch != Width*BytesPerPixel
-               // Copy to Frambuffer
-               dest = (Uint8 *)FBInfo->Framebuffer + Offset;
-               memcpy(dest, Buffer, Length);
+               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;
+
+                               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:
@@ -225,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;
@@ -253,29 +306,34 @@ void DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *B
        {
                Buf->CursorX = -1;
                Buf->CursorY = -1;
-               return ;
+               return 0;
        }
 
-       if( Bitmap != &gDrvUtil_TextModeCursor )
+       // 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);
+               errno = -EINVAL;
+               return -1;
+       }
+
+       // Don't take a copy of the DrvUtil provided cursor
+       if( Bitmap == &gDrvUtil_TextModeCursor )
+       {
+               Buf->CursorBitmap = Bitmap;
+       }
+       else
        {
-               // Check the new bitmap is valid
                size = sizeof(tVideo_IOCtl_Bitmap) + Bitmap->W*Bitmap->H*4;
-               if( !CheckMem(Bitmap, size) ) {
-                       Log_Warning("DrvUtil", "DrvUtil_Video_SetCursor: Bitmap (%p) is in invalid memory", Bitmap);
-                       return;
-               }
                
                // Take a copy
                Buf->CursorBitmap = malloc( size );
                memcpy(Buf->CursorBitmap, Bitmap, size);
        }
-       else
-       {
-               Buf->CursorBitmap = &gDrvUtil_TextModeCursor;
-       }
        
        // Restore cursor position
        DrvUtil_Video_DrawCursor(Buf, csrX, csrY);
+       return 0;
 }
 
 void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
@@ -332,8 +390,6 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
        Uint32  *src;
         int    x, y;
 
-//     Debug("DrvUtil_Video_RenderCursor: (Buf=%p) dest_x=%i, dest_y=%i", Buf, dest_x, dest_y);
-
        dest = (Uint8*)Buf->Framebuffer + dest_y*Buf->Pitch + dest_x*bytes_per_px;
        src = Buf->CursorBitmap->Data + src_y * Buf->CursorBitmap->W + src_x;
        
@@ -348,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
                        }
@@ -367,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;
        }
 }
@@ -452,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 -- ) {

UCC git Repository :: git.ucc.asn.au