X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=inline;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fvideo.c;h=3916baa1f6061d572b9ba27e1f05e93adfaf9ee4;hb=21192b41da0f87dba07dac08b2d814b0976d929c;hp=393d5bf43772de2cc9223a4c5c3417a4ee283f79;hpb=d2e9501431148e85345cefe6315f0eace0dfd777;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index 393d5bf4..3916baa1 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -13,18 +13,23 @@ #include #include #include +#include + +// === IMPORTS === +extern int giTerminalFD_Input; // === PROTOTYPES === void Video_Setup(void); void Video_SetCursorPos(short X, short Y); void Video_Update(void); -void Video_FillRect(short X, short Y, short W, short H, uint32_t Color); -void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color); +void Video_FillRect(int X, int Y, int W, int H, uint32_t Color); // === GLOBALS === int giVideo_CursorX; int giVideo_CursorY; uint32_t *gpScreenBuffer; + int giVideo_FirstDirtyLine; + int giVideo_LastDirtyLine; // === CODE === void Video_Setup(void) @@ -32,13 +37,25 @@ void Video_Setup(void) int tmpInt; // Open terminal + #if 0 giTerminalFD = open(gsTerminalDevice, OPENFLAG_READ|OPENFLAG_WRITE); if( giTerminalFD == -1 ) { fprintf(stderr, "ERROR: Unable to open '%s' (%i)\n", gsTerminalDevice, _errno); exit(-1); } - + #else + giTerminalFD = 1; + giTerminalFD_Input = 0; + // Check that the console is a VT + // - ioctl(..., 0, NULL) returns the type, which should be 2 + if( ioctl(1, 0, NULL) != 2 ) + { + fprintf(stderr, "stdout is not an Acess VT, can't start"); + _SysDebug("stdout is not an Acess VT, can't start"); + exit(-1); + } + #endif // Set mode to video tmpInt = TERM_MODE_FB; @@ -47,6 +64,8 @@ void Video_Setup(void) // Get dimensions giScreenWidth = ioctl( giTerminalFD, TERM_IOCTL_WIDTH, NULL ); giScreenHeight = ioctl( giTerminalFD, TERM_IOCTL_HEIGHT, NULL ); + + giVideo_LastDirtyLine = giScreenHeight; // Force VT to be shown ioctl( giTerminalFD, TERM_IOCTL_FORCESHOW, NULL ); @@ -61,10 +80,19 @@ void Video_Setup(void) void Video_Update(void) { - _SysDebug("Video_Update - gpScreenBuffer[0] = 0x%x", gpScreenBuffer[0]); - seek(giTerminalFD, 0, 1); - write(giTerminalFD, gpScreenBuffer, giScreenWidth*giScreenHeight*4); + int ofs = giVideo_FirstDirtyLine*giScreenWidth; + int size = (giVideo_LastDirtyLine-giVideo_FirstDirtyLine)*giScreenWidth; + + if( giVideo_LastDirtyLine == 0 ) return; + + _SysDebug("Video_Update - Updating lines %i to %i (0x%x+0x%x px)", + giVideo_FirstDirtyLine, giVideo_LastDirtyLine, ofs, size); + seek(giTerminalFD, ofs*4, 1); + _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4); + write(giTerminalFD, gpScreenBuffer+ofs, size*4); _SysDebug("Video_Update - Done"); + giVideo_FirstDirtyLine = 0; + giVideo_LastDirtyLine = 0; } void Video_SetCursorPos(short X, short Y) @@ -78,17 +106,33 @@ void Video_SetCursorPos(short X, short Y) ioctl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos); } +void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour) +{ + uint32_t *dest; + int i; + + if(X < 0 || Y < 0) return; + if(W >= giScreenWidth) return; + if(H >= giScreenHeight) return; + if(X + W >= giScreenWidth) W = giScreenWidth - W; + if(Y + H >= giScreenHeight) W = giScreenHeight - H; + + dest = gpScreenBuffer + Y * giScreenWidth + X; + while(H --) + { + for( i = W; i --; dest ++ ) *dest = Colour; + dest += giScreenWidth - W; + } +} + /** * \brief Blit an entire buffer to the screen * \note Assumes Pitch = 4*W */ void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H) { - int i; uint32_t *buf; -// _SysDebug("Video_Blit: (%p (%i, %i) %ix%i)", Source, DstX, DstY, W, H); - if( DstX >= giScreenWidth) return ; if( DstY >= giScreenHeight) return ; // TODO: Handle -ve X/Y by clipping @@ -96,18 +140,28 @@ void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H) // TODO: Handle out of bounds by clipping too if( DstX + W > giScreenWidth ) return; if( DstY + H > giScreenHeight ) - H = giScreenWidth - DstY; + H = giScreenHeight - DstY; if( W <= 0 || H <= 0 ) return; + + if( DstX < giVideo_FirstDirtyLine ) + giVideo_FirstDirtyLine = DstY; + if( DstY + H > giVideo_LastDirtyLine ) + giVideo_LastDirtyLine = DstY + H; -// _SysDebug(" Clipped to (%i, %i) %ix%i", DstX, DstY, W, H); -// _SysDebug(" Source[0] = 0x%x", Source[0]); buf = gpScreenBuffer + DstY*giScreenWidth + DstX; - while( H -- ) + if(W != giScreenWidth) + { + while( H -- ) + { + memcpy(buf, Source, W*4); + Source += W; + buf += giScreenWidth; + } + } + else { - for( i = W; i --; ) - *buf++ = *Source++; - buf += giScreenWidth - W; + memcpy(buf, Source, giScreenWidth*H*4); } }