_getimage() and _putimage() Functionality in Text Mode

Last reviewed: July 22, 1997
Article ID: Q123875
6.00 6.00a 6.00ax 7.00 | 1.00 1.50
MS-DOS                 | WINDOWS
kbprg kbcode

The information in this article applies to:

   The C Run-time (CRT) included with:
     - Microsoft C versions 6.0, 6.0a, and 6.0ax
     - Microsoft C/C++ version 7.0
     - Microsoft Visual C++ for Windows, versions 1.0 and 1.5

SUMMARY

The graphics library that ships with Microsoft C contains the functions _getimage() and _putimage() to read and write blocks of video memory. There is also a function called _imagesize() that you can use to determine the size of a buffer required to store an image. These image functions work only in graphics modes. To obtain the functionality of _getimage() and _putimage in a text mode, you need to create a pointer to video memory, and access video memory directly through this pointer.

MORE INFORMATION

In the MS-DOS environment, video memory begins at segment 0xB000 for monochrome text modes and segment 0xB800 for color text modes. Each character is represented by two bytes; a byte containing the ASCII value of the character to display and an additional byte representing the attributes of the character. Attributes supported in monochrome modes include bold and underline, while color mode attributes include foreground and background color.

The sample code in this article uses the _FP_SEG and _FP_OFF macros to initialize a global pointer to video memory (lpVM). Then it writes text to the screen, allocates memory to store a text block, reads a text block from the display, and writes that block to a new area of the display.

Sample Code

/* Compile Options needed: /AL
*/

#include <dos.h>
#include <conio.h>
#include <memory.h>
#include <malloc.h>
#include <process.h>
#include <stdio.h>

char * lpVM;    // Global pointer to video memory - set in main()

/* Calculates offset from beginning of video memory to screen position */
int VidOff(int column, int row)
{
    return ( ( row * 80 ) + column ) * 2;
}

void PutChar(char c, int x, int y)
{
    *(lpVM+VidOff(x,y)) = c;
}

char GetChar(int x, int y)
{
    return *(lpVM+VidOff(x,y));
}

/* Reads block of video memory matching rectangular coordinates
** into buffer (buf) note: buf must have been allocated with enough ** space for the block. Similar to graphics.lib function _getimage().
*/
void ReadBlock( char * buf, int left, int top, int right, int bottom)
{
    int row, destoffset, vidoffset;
    size_t rowsize;

    rowsize = ( right - left + 1 ) * 2;

    for ( row=top, destoffset=0; row<=bottom; row++,
          destoffset+=rowsize )
    {
        vidoffset = VidOff(left, row);
        memcpy( buf+destoffset, lpVM+vidoffset, rowsize);
    }
}

/* Writes contents of buf to video memory matching coordinates.
** Similar to graphics.lib function _putimage().
*/
void WriteBlock( char * buf, int left, int top, int right, int bottom)
{
    int row, destoffset, vidoffset;
    size_t rowsize;

    rowsize = ( right - left + 1 ) * 2;

    for ( row=top, destoffset=0; row<=bottom; row++,
          destoffset+=rowsize )
    {
        vidoffset = VidOff(left, row);
        memcpy( lpVM+vidoffset, buf+destoffset, rowsize);
    }
}

/* Calculates size requires for block of video memory fitting
** coordinates and allocates space with malloc. Similar to ** graphics.lib function _imagesize(), but actually allocates ** the memory.
*/
void * AllocBlock( int left, int top, int right, int bottom)
{
    size_t blocksize;

    blocksize = ( ( right - left + 1) * ( bottom - top + 1) ) * 2;

    return malloc( blocksize );
}

void main(void)
{
    int i,j;

    char * buf;

    system( "cls" );              // clear the display

    _FP_SEG( lpVM ) = 0xB800;     // B000 if monochrome
    _FP_OFF( lpVM ) = 0x0000;

    for (i=1; i<20; i++)
    {
          PutChar( '\\', i, i );
          PutChar( '/', 80-i, i );
    }

    buf = AllocBlock( 5, 5, 80, 15 );

    ReadBlock( buf, 5, 5, 80, 15 );

    printf( "Block read. Press \"Enter\" to write block.\n" );

    getch();

    WriteBlock( buf, 5, 10, 80, 20 );

    getch();
    system( "cls" );              // clear the display
}

REFERENCES

Programmmer's Guide to PC & PS/2 Video Systems by Richard Wilton (Microsoft Press)


Additional reference words: kbinf 6.00 6.00a 6.00ax 7.00 1.00 1.50
KBCategory: kbprg kbcode
KBSubcategory: CRTIss GraphicsIss
Keywords : kb16bitonly


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.