home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------
- //
- // File: DISPLAY.CPP
- // Path: ...\REHACK\graphics
- // Version: 1.1
- // Author: Dave Boynton
- // CIS Id: 71043,317
- // Created On: 6/26/93
- // Modified On: 7/25/93
- // Description: display class methods for mode 13h, 320x200 256c
- // Tabs: 4
- //
- //---------------------------------------------------------------------------
- // copyright (c) 1993 by the GAMERS Forum, Rehack project team.
- // All rights reserved.
- #include <dos.h>
- #include <mem.h>
- #include "bitmap.hpp"
- #include "display.hpp"
-
- //----------------------------- DisplayManager ---------------------------
- //DisplayManager display(0); //wait for retraces, refuse direct bitmaps
- //DisplayManager display(1); //don't do retraces, allow direct bitmaps
- #pragma argsused
- DisplayManager::DisplayManager(word flags)
- {
- size.x=getWidth(); size.y=getHeight();
- videoSegment=0xA000U; // bad news for extenders! But seriously, if an
- // extender is used, this line needs to be changed
- // to map a selector to 0xA0000000UL, size 64k.
- bounds.topLeft.x=0;
- bounds.topLeft.y=0;
- bounds.bottomRight.x=getWidth();
- bounds.bottomRight.y=getHeight();
-
- if ( (flags & 0x01) == 0x01 )
- retrace=false; //modern SVGA cards aren't as touchy, don't need it.
- // but I'm leaving it up to main() to decide.
- else
- retrace=true;
- }
-
- // put src's viewPort onto the screen, relative to it's ownerBounds, using
- // the full size of the viewPort.
- void DisplayManager::putBitmap(Bitmap * src)
- {
- if ( src->directFlag )
- return;
-
- word sizeX, sizeY;
- sizeX=src->viewPort.bottomRight.x - src->viewPort.topLeft.x;
- sizeY=src->viewPort.bottomRight.y - src->viewPort.topLeft.y;
-
- putBitmap(src, (src->ownerBounds.topLeft.x + src->viewPort.topLeft.x),
- (src->ownerBounds.topLeft.y + src->viewPort.topLeft.y),
- sizeX, sizeY);
- }
-
- // put src's viewPort onto the screen, at offset "at", using the full size
- // of the viewPort. I haven't tested this one with anything yet; not sure
- // if it's even useful.
- void DisplayManager::putBitmap(Bitmap * src, const Point &at)
- {
- if ( src->directFlag )
- return;
-
- word sizeX, sizeY;
- sizeX=src->viewPort.bottomRight.x - src->viewPort.topLeft.x;
- sizeY=src->viewPort.bottomRight.y - src->viewPort.topLeft.y;
-
- putBitmap(src, at.x, at.y, sizeX, sizeY);
- }
-
- // put src's viewPort onto the display, using screen offset xoff,yoff
- // and size xsize, ysize.
- void DisplayManager::putBitmap(Bitmap * src,int xoff,int yoff, int xsize, int ysize)
- {
- if ( src->directFlag )
- return;
-
- if ( (xoff+xsize) > size.x )
- xsize=size.x - xoff;
-
- if ( (yoff+ysize) > size.y )
- ysize=size.y - yoff;
-
- if ( ( ysize < 1 ) || ( xsize < 1 ) )
- return;
-
- word srcWidth=src->localBounds.bottomRight.x - src->localBounds.topLeft.x;
- word destWidth=size.x;
-
- byte * srcPtr= (src->viewPort.topLeft.y * srcWidth) +
- src->viewPort.topLeft.x + src->bits;
- byte * destPtr=(byte *) MK_FP(videoSegment,(yoff*destWidth + xoff));
-
- int i;
- for (i=src->viewPort.topLeft.y; i<src->viewPort.bottomRight.y; i++)
- {
- memcpy(destPtr, srcPtr, xsize);
- srcPtr+= srcWidth;
- destPtr+= destWidth;
- }
- }
-
- void DisplayManager::putBitmap(Bitmap *src, const Rect &destRect)
- {
- byte * destPtr;
- byte * srcPtr;
- word srcWidth, destWidth;
- Rect srcRect, // subset of src->viewPort
- copyRect, // subset of bounds & destRect
- copySize; // 0,0 based copy size
-
- if ( src->directFlag )
- return;
-
- copyRect= destRect & bounds; // display bounds
- destWidth=size.x;
-
- copySize=(copyRect - copyRect.topLeft) &
- (src->viewPort - src->viewPort.topLeft);
- srcWidth=src->localBounds.bottomRight.x - src->localBounds.topLeft.x;
-
- srcPtr=(src->viewPort.topLeft.y * srcWidth) + src->viewPort.topLeft.x +
- src->bits;
- destPtr=(byte *) MK_FP(videoSegment,
- (copyRect.topLeft.y*destWidth + copyRect.topLeft.x));
-
- int i;
- for (i=src->viewPort.topLeft.y; i<src->viewPort.bottomRight.y; i++)
- {
- memcpy(destPtr, srcPtr, destWidth);
- srcPtr+= srcWidth;
- destPtr+= destWidth;
- }
- }
-
- // get a direct Bitmap of the full screen. This could be static, except for
- // the use of videoSegment, which must be initialized first.
- Bitmap * DisplayManager::getDirectBitmap(void)
- {
- Bitmap * fullscreen = new Bitmap(size.x, size.y, true);
-
- fullscreen->bits=(byte *) MK_FP(videoSegment,0);
- return fullscreen;
- }
-
- // Calls video interrupt to set graphics adaptor to mode
- void DisplayManager::setMode(const int mode)
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = 0x00;
- inregs.h.al = mode;
- int86(0x10, &inregs, &outregs);
- }
-
- // setpalette()
- // Sets all 256 VGA color registers to RGB values in colregs[]
- // (asm unnecessary for this function! will be changed!)
- void DisplayManager::setPalette(const byte *palette)
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
-
- inregs.h.ah = 0x10;
- inregs.h.al = 0x12;
- inregs.x.bx = 0;
- inregs.x.cx = 0xff;
- segregs.es=FP_SEG(palette);
- inregs.x.dx = FP_OFF(palette);
- int86x(0x10, &inregs, &outregs, &segregs);
- }
-
- // Loop to delay until next vertical blank
- void DisplayManager::waitForVerticalRetrace(void)
- {
- while ((inport(0x3da)&8)==0);
- }
-
- void DisplayManager::blankScreen(void)
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x1201;
- inregs.h.bl = 0x36;
- int86(0x10, &inregs, &outregs);
- }
-
- void DisplayManager::unblankScreen(void)
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x1200;
- inregs.h.bl = 0x36;
- int86(0x10, &inregs, &outregs);
- }
-
- // replaces __assertfail, used by <assert.h>, which doesn't expect to be
- // in graphics mode.
- void DisplayManager::assertfail( char *__msg, char *__cond,
- char *__file, int __line)
- {
- DisplayManager::setMode(3);
- ::__assertfail(__msg,__cond,__file,__line);
- }
-