X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin4_src%2FServer%2Fvideo.cpp;h=50686c61be17f5e1d7b22b31a5ea8206c1b2ddf8;hb=4d0188930e7d0e571db78d1d2e3c4d9b3f0fe8fb;hp=a3949221f198161376a09ed596a6d2a37a12f78c;hpb=340e7923b1e95c39ac85a4b22af7f1b53b315cd9;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin4_src/Server/video.cpp b/Usermode/Applications/axwin4_src/Server/video.cpp index a3949221..50686c61 100644 --- a/Usermode/Applications/axwin4_src/Server/video.cpp +++ b/Usermode/Applications/axwin4_src/Server/video.cpp @@ -5,17 +5,116 @@ * video.cpp * - Graphics output */ +#include #include +#include + +extern "C" { +#include +#include +#include +#include "resources/cursor.h" +} namespace AxWin { -namespace Graphics { +CVideo::CVideo(const CConfigVideo& config): + m_fd(1), + m_width(0), + m_height(0), + m_bufferFormat(PTYBUFFMT_TEXT) +{ + // Obtain dimensions + { + if( _SysIOCtl(m_fd, DRV_IOCTL_TYPE, NULL) != DRV_TYPE_TERMINAL ) + throw AxWin::InitFailure("stdin isn't a terminal"); + struct ptydims dims; + if( _SysIOCtl(m_fd, PTY_IOCTL_GETDIMS, &dims) == -1 ) + throw AxWin::InitFailure("Failed to get dimensions from stdin"); + m_width = dims.PW; + m_height = dims.PH; + if( m_width == 0 || m_height == 0 ) + throw AxWin::InitFailure("Terminal not capable of graphics"); + } + + _SysDebug("m_width=%i, m_height=%i", m_width, m_height); + SetCursorBitmap(); + + SetCursorPos( m_width/2, m_height/2 ); + + SetBufFormat(PTYBUFFMT_FB); + uint32_t data[m_width]; + for( unsigned int i = 0; i < m_height; i ++ ) + BlitLine(data, i, 0, m_width); +} + +void CVideo::GetDims(unsigned int& w, unsigned int& h) +{ + w = m_width; + h = m_height; +} + +void CVideo::BlitLine(const uint32_t* src, unsigned int dst_y, unsigned int dst_x, unsigned int width) +{ + //_SysDebug("CVideo::BlitLine (%p, %i, %i, %i)", src, dst_y, dst_x, width); + //_SysDebugHex("CVideo::BlitLine", src, width*4); + size_t cmdlen = (sizeof(struct ptycmd_senddata) + width*4)/4; + //_SysDebug(" - Offset = %i, cmdlen = %i", (dst_y * m_width + dst_x) * 4, cmdlen); + struct ptycmd_senddata cmd = { + {PTY2D_CMD_SEND, uint8_t(cmdlen & 0xFF), uint16_t(cmdlen>>8)}, + (dst_y * m_width + dst_x) + }; + SetBufFormat(PTYBUFFMT_2DCMD); + _SysWrite(m_fd, &cmd, sizeof(cmd)); + _SysWrite(m_fd, src, width*4); +} -void Initialise(const CConfigVideo& config) +void CVideo::Flush() { + // TODO: Write to a local copy of the framebuffer in BlitLine, and then flush out in this function } -}; +void CVideo::SetBufFormat(unsigned int FormatID) +{ + if( m_bufferFormat != FormatID ) + { + + struct ptymode mode = {.OutputMode = FormatID, .InputMode = 0}; + int rv = _SysIOCtl( m_fd, PTY_IOCTL_SETMODE, &mode ); + if( rv ) { + throw ::AxWin::InitFailure("Can't set PTY to framebuffer mode"); + } + + m_bufferFormat = FormatID; + } +} + +void CVideo::SetCursorBitmap() +{ + // Set cursor position and bitmap + struct ptycmd_header hdr = {PTY2D_CMD_SETCURSORBMP,0,0}; + size_t size = sizeof(hdr) + sizeof(cCursorBitmap) + cCursorBitmap.W*cCursorBitmap.H*4; + hdr.len_low = size / 4; + hdr.len_hi = size / (256*4); + + SetBufFormat(PTYBUFFMT_2DCMD); + _SysWrite(m_fd, &hdr, sizeof(hdr)); + _SysDebug("SetCursorBitmap - size = %i (%04x:%02x * 4)", size, hdr.len_hi, hdr.len_low); + _SysWrite(m_fd, &cCursorBitmap, size-sizeof(hdr)); +} + +void CVideo::SetCursorPos(int X, int Y) +{ + struct ptycmd_setcursorpos cmd; + cmd.hdr.cmd = PTY2D_CMD_SETCURSORPOS; + cmd.hdr.len_low = sizeof(cmd)/4; + cmd.hdr.len_hi = 0; + cmd.x = X; + cmd.y = Y; + + SetBufFormat(PTYBUFFMT_2DCMD); + _SysWrite(m_fd, &cmd, sizeof(cmd)); +} }; // namespace AxWin