Merge branch 'master' of git://cadel.mutabah.net/acess2
[tpg/acess2.git] / KernelLand / Kernel / drvutil_video.c
index 6e63386..2bffb1a 100644 (file)
@@ -58,6 +58,9 @@ int DrvUtil_Video_2DStream(void *Ent, const void *Buffer, int Length,
        const Uint8     *stream = Buffer;
         int    rem = Length;
         int    op;
+
+       Uint16  tmp[6];
+
        while( rem )
        {
                rem --;
@@ -83,7 +86,8 @@ int DrvUtil_Video_2DStream(void *Ent, const void *Buffer, int Length,
                case VIDEO_2DOP_NOP:    break;
                
                case VIDEO_2DOP_FILL:
-                       if(rem < 10)    return Length-rem;
+                       if(rem < 12)    return Length-rem;
+                       memcpy(tmp, stream, 6*2);
                        
                        if(!Handlers->Fill) {
                                Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
@@ -92,18 +96,18 @@ int DrvUtil_Video_2DStream(void *Ent, const void *Buffer, int Length,
                        }
                        
                        Handlers->Fill(
-                               Ent,
-                               ((const Uint16*)stream)[0], ((const Uint16*)stream)[1],
-                               ((const Uint16*)stream)[2], ((const Uint16*)stream)[3],
-                               ((const Uint32*)stream)[4]
+                               Ent, 
+                               tmp[0], tmp[1], tmp[2], tmp[3],
+                               tmp[4] | ((Uint32)tmp[5] << 16)
                                );
                        
-                       rem -= 10;
-                       stream += 10;
+                       rem -= 12;
+                       stream += 12;
                        break;
                
                case VIDEO_2DOP_BLIT:
                        if(rem < 12)    return Length-rem;
+                       memcpy(tmp, stream, 6*2);
                        
                        if(!Handlers->Blit) {
                                Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
@@ -113,9 +117,8 @@ int DrvUtil_Video_2DStream(void *Ent, const void *Buffer, int Length,
                        
                        Handlers->Blit(
                                Ent,
-                               ((const Uint16*)stream)[0], ((const Uint16*)stream)[1],
-                               ((const Uint16*)stream)[2], ((const Uint16*)stream)[3],
-                               ((const Uint16*)stream)[4], ((const Uint16*)stream)[5]
+                               tmp[0], tmp[1], tmp[2], tmp[3],
+                               tmp[4], tmp[5]
                                );
                        
                        rem -= 12;
@@ -134,12 +137,18 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
         int    csr_x, csr_y;
         int    x, y;
         int    bytes_per_px = (FBInfo->Depth + 7) / 8;
+       size_t  ofs;
        ENTER("pFBInfo xOffset xLength pBuffer",
                FBInfo, Offset, Length, Buffer);
 
        csr_x = FBInfo->CursorX;
        csr_y = FBInfo->CursorY;
 
+       if( FBInfo->BackBuffer )
+               dest = FBInfo->BackBuffer;
+       else
+               dest = FBInfo->Framebuffer;
+       
        DrvUtil_Video_RemoveCursor(FBInfo);
 
        switch( FBInfo->BufferFormat )
@@ -168,10 +177,9 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                        Length = heightInChars*widthInChars - Offset;
                }
                
-               dest = FBInfo->Framebuffer;
-               LOG("dest = %p", dest);
-               dest += y * giVT_CharHeight * FBInfo->Pitch;
                LOG("dest = %p", dest);
+               ofs = y * giVT_CharHeight * FBInfo->Pitch;
+               dest += ofs;
                
                for( i = 0; i < Length; i++ )
                {
@@ -198,9 +206,11 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                                LOG("dest = %p", dest);
                        }
                }
+               if( x > 0 ) 
+                       dest += FBInfo->Pitch*giVT_CharHeight;
                Length = i * sizeof(tVT_Char);
-               }
-               break;
+               
+               break; }
        
        case VIDEO_BUFFMT_FRAMEBUFFER:
                if(FBInfo->Width*FBInfo->Height*4 < Offset+Length)
@@ -214,11 +224,13 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                case 15:
                case 16:
                        Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in LFB write");
+                       dest = NULL;
                        break;
                case 24:
                        x = Offset % FBInfo->Width;
                        y = Offset / FBInfo->Width;
-                       dest = (Uint8*)FBInfo->Framebuffer + y*FBInfo->Pitch;
+                       ofs = y*FBInfo->Pitch;
+                       dest += ofs;
                        for( ; Length >= 4; Length -= 4 )
                        {
                                dest[x*3+0] = *src & 0xFF;
@@ -240,25 +252,34 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                                x = Offset % FBInfo->Width;
                                y = Offset / FBInfo->Height;
                                
-                               px = (Uint32*)FBInfo->Framebuffer + y*FBInfo->Pitch/4;
+                               ofs = y*FBInfo->Pitch;
+                               dest += ofs;
+                               px = (void*)dest;
 
-                               for( ; Length >= 4; Length -= 4, x )
+                               for( ; Length >= 4; Length -= 4 )
                                {
                                        px[x++] = *src ++;
                                        if( x == FBInfo->Width ) {
                                                x = 0;
-                                               px += FBInfo->Pitch;
+                                               dest += FBInfo->Pitch;
+                                               px = (void*)dest;
                                        }
                                }
+                               if( x > 0 ) {
+                                       dest += FBInfo->Pitch;
+                               }
                        }
                        else
                        {
-                               dest = (Uint8 *)FBInfo->Framebuffer + Offset;
+                               ofs = Offset;
+                               dest += ofs;
                                memcpy(dest, Buffer, Length);
+                               dest += Length;
                        }
                        break;
                default:
-                       Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Unknown bit depthn %i", FBInfo->Depth);
+                       Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Unknown bit depth %i", FBInfo->Depth);
+                       dest = NULL;
                        break;
                }
                break;
@@ -268,12 +289,20 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
                        FBInfo, Buffer, Length,
                        &gDrvUtil_Stub_2DFunctions, sizeof(gDrvUtil_Stub_2DFunctions)
                        );
+               dest = NULL;
                break;
        
        default:
                LEAVE('i', -1);
                return -1;
        }
+       if( FBInfo->BackBuffer && dest ) {
+               void    *_dst = (char*)FBInfo->Framebuffer + ofs;
+               void    *_src = (char*)FBInfo->BackBuffer + ofs;
+               size_t  len = ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs;
+       //      Log_Debug("DrvUtil", "Copy from BB %p to FB %p 0x%x bytes", _src, _dst, len);
+               memcpy(_dst, _src, len);
+       }
 
        DrvUtil_Video_DrawCursor(FBInfo, csr_x, csr_y);
 
@@ -321,6 +350,12 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
                LEAVE('i', -1);
                return -1;
        }
+       ASSERTCR(Bitmap->W, >, 0, -1);
+       ASSERTCR(Bitmap->H, >, 0, -1);
+       ASSERTCR(Bitmap->XOfs, <, Bitmap->W, -1);
+       ASSERTCR(Bitmap->XOfs, >, -Bitmap->W, -1);
+       ASSERTCR(Bitmap->YOfs, <, Bitmap->H, -1);
+       ASSERTCR(Bitmap->YOfs, >, -Bitmap->H, -1);
 
        // Don't take a copy of the DrvUtil provided cursor
        if( Bitmap == &gDrvUtil_TextModeCursor )
@@ -378,8 +413,18 @@ void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
        Y -= Buf->CursorBitmap->YOfs;
        
        // Get the width of the cursor on screen (clipping to right/bottom edges)
-       render_w = X > Buf->Width  - Buf->CursorBitmap->W ? Buf->Width  - X : Buf->CursorBitmap->W;
-       render_h = Y > Buf->Height - Buf->CursorBitmap->H ? Buf->Height - Y : Buf->CursorBitmap->H;
+       ASSERTC(Buf->Width, >, 0);
+       ASSERTC(Buf->Height, >, 0);
+       ASSERTC(Buf->CursorBitmap->W, >, 0);
+       ASSERTC(Buf->CursorBitmap->H, >, 0);
+       
+       render_w = MIN(Buf->Width  - X, Buf->CursorBitmap->W);
+       render_h = MIN(Buf->Height - Y, Buf->CursorBitmap->H);
+       //render_w = X > Buf->Width  - Buf->CursorBitmap->W ? Buf->Width  - X : Buf->CursorBitmap->W;
+       //render_h = Y > Buf->Height - Buf->CursorBitmap->H ? Buf->Height - Y : Buf->CursorBitmap->H;
+
+       ASSERTC(render_w, >=, 0);
+       ASSERTC(render_h, >=, 0);
 
        // Clipp to left/top edges
        if(X < 0) {     render_ox = -X; X = 0;  }
@@ -418,6 +463,9 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
        if( !Buf->CursorSaveBuf )
                Buf->CursorSaveBuf = malloc( Buf->CursorBitmap->W*Buf->CursorBitmap->H*bytes_per_px );
 
+       ASSERTC(render_w, >=, 0);
+       ASSERTC(render_h, >=, 0);
+
        LOG("Saving back");
        // Save behind the cursor
        for( y = 0; y < render_h; y ++ )
@@ -432,7 +480,8 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
        {
        case 15:
        case 16:
-               Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in cursor draw");
+               //Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in cursor draw");
+               //Proc_PrintBacktrace();
                break;
        case 24:
                LOG("24-bit render");
@@ -487,8 +536,6 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
 void DrvUtil_Video_RemoveCursor(tDrvUtil_Video_BufInfo *Buf)
 {
         int    bytes_per_px = (Buf->Depth + 7) / 8;
-        int    y, save_pitch;
-       Uint8   *dest, *src;
 
        // Just a little sanity
        if( !Buf->CursorBitmap || Buf->CursorX == -1 )  return ;
@@ -497,16 +544,21 @@ void DrvUtil_Video_RemoveCursor(tDrvUtil_Video_BufInfo *Buf)
 //     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;
-       src = Buf->CursorSaveBuf;
-       
+       size_t  save_pitch = Buf->CursorBitmap->W * bytes_per_px;
+       Uint8   *dst = (Uint8*)Buf->Framebuffer + Buf->CursorDestY * Buf->Pitch + Buf->CursorDestX*bytes_per_px;
+       const Uint8     *src = Buf->CursorSaveBuf;
+
+       ASSERT(Buf->Framebuffer);
+       ASSERT(src);
+       ASSERT(CheckMem(dst, Buf->CursorRenderH*Buf->Pitch));
+       ASSERT(CheckMem(src, Buf->CursorRenderH*save_pitch));
+
        // Copy each line back
-       for( y = 0; y < Buf->CursorRenderH; y ++ )
+       for( int y = 0; y < Buf->CursorRenderH; y ++ )
        {
-               memcpy( dest, src, Buf->CursorRenderW * bytes_per_px );
+               memcpy( dst, src, Buf->CursorRenderW * bytes_per_px );
                src += save_pitch;
-               dest += Buf->Pitch;
+               dst += Buf->Pitch;
        }
        
        // Set the cursor as removed
@@ -517,18 +569,35 @@ void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Ui
 {
        tDrvUtil_Video_BufInfo  *FBInfo = Ent;
 
-       // TODO: Handle non-32bit modes
-       if( FBInfo->Depth != 32 )       return;
-
-       // TODO: Be less hacky
-        int    pitch = FBInfo->Pitch/4;
-       Uint32  *buf = (Uint32*)FBInfo->Framebuffer + Y*pitch + X;
-       while( H -- ) {
-               Uint32 *tmp;
-                int    i;
-               tmp = buf;
-               for(i=W;i--;tmp++)      *tmp = Colour;
-               buf += pitch;
+       switch( FBInfo->Depth )
+       {
+       case 32: {
+               // TODO: Be less hacky
+               size_t  pitch = FBInfo->Pitch/4;
+               size_t  ofs = Y*pitch + X;
+               Uint32  *buf = (Uint32*)FBInfo->Framebuffer + ofs;
+               Uint32  *cbuf = NULL;
+               if( FBInfo->BackBuffer )
+                       cbuf = (Uint32*)FBInfo->BackBuffer + ofs;
+               while( H -- )
+               {
+                       Uint32 *line;
+                       line = buf;
+                       for(int i = W; i--; line++)
+                               *line = Colour;
+                       buf += pitch;
+                       if( cbuf ) {
+                               line = cbuf;
+                               for(int i = W; i--; line++ )
+                                       *line = Colour;
+                               cbuf += pitch;
+                       }
+               }
+               break; }
+       default:
+               // TODO: Handle non-32bit modes
+               Log_Warning("DrvUtil", "TODO: <32bpp _Fill");
+               break;
        }
 }
 
@@ -540,6 +609,9 @@ void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uin
         int    dst = DstY*scrnpitch + DstX;
         int    src = SrcY*scrnpitch + SrcX;
         int    tmp;
+       Uint8   *framebuffer = FBInfo->Framebuffer;
+       Uint8   *backbuffer = FBInfo->BackBuffer;
+       Uint8   *sourcebuffer = (FBInfo->BackBuffer ? FBInfo->BackBuffer : FBInfo->Framebuffer);
        
        //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",
        //      Ent, DstX, DstY, SrcX, SrcY, W, H);
@@ -551,26 +623,39 @@ void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uin
        
        //Debug("W = %i, H = %i", W, H);
        
-       if( dst > src ) {
+       if(W == FBInfo->Width && FBInfo->Pitch == FBInfo->Width*bytes_per_px)
+       {
+               memmove(framebuffer + dst, sourcebuffer + src, H*FBInfo->Pitch);
+               if( backbuffer )
+                       memmove(backbuffer + dst, sourcebuffer + src, H*FBInfo->Pitch);
+       }
+       else if( dst > src )
+       {
                // Reverse copy
                dst += H*scrnpitch;
                src += H*scrnpitch;
-               while( H -- ) {
+               while( H -- )
+               {
                        dst -= scrnpitch;
                        src -= scrnpitch;
                        tmp = W*bytes_per_px;
-                       for( tmp = W; tmp --; ) {
-                               *((Uint8*)FBInfo->Framebuffer + dst + tmp) = *((Uint8*)FBInfo->Framebuffer + src + tmp);
+                       for( tmp = W; tmp --; )
+                       {
+                               size_t  src_o = src + tmp;
+                               size_t  dst_o = src + tmp;
+                               framebuffer[dst_o] = sourcebuffer[src_o];
+                               if( backbuffer )
+                                       backbuffer[dst_o] = sourcebuffer[src_o];
                        }
                }
        }
-       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 -- ) {
-                       memcpy((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, W*bytes_per_px);
+               while( H -- )
+               {
+                       memcpy(framebuffer + dst, sourcebuffer + src, W*bytes_per_px);
+                       if( backbuffer )
+                               memcpy(backbuffer + dst, sourcebuffer + src, W*bytes_per_px);
                        dst += scrnpitch;
                        src += scrnpitch;
                }

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