home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / rehack / demosrc / gscreen.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-07  |  5.4 KB  |  272 lines

  1. //        Gscreen.cpp
  2.  
  3. #ifndef gscreen_cpp
  4. #define gscreen_cpp
  5.  
  6. #ifdef Gscreen_test
  7. #include "Gscreen.hpp"
  8. #else
  9. #include <Gscreen.hpp>
  10. #endif
  11.  
  12. void BitMap::erase (void) {
  13.     int scrx=screnx;
  14.     int scry=screny;
  15.  
  16.     int hline=maxx;                // set from Gscreen's maxx
  17.     unsigned int offscr=(unsigned int)scrx+
  18.         ((unsigned int)scry*(unsigned int)hline);
  19.  
  20.     int d_blockx=blockx;
  21.     int d_blocky=blocky;
  22.     int d_totalx=totalx;
  23.  
  24.     wait_for_vbl();
  25.     asm {
  26.         push    bx
  27.         push    cx
  28.         push    dx
  29.         push    ds
  30.         mov    dx,d_blocky                    // vertical count
  31.         push    0a000h                        // video memory segment
  32.         pop    es
  33.         mov    bx,offscr                    // bx to upper left of block
  34.     }
  35.     row:
  36.     asm {
  37.         mov    cx,d_blockx                    // horizontal count
  38.     }
  39.     col:
  40.     asm {
  41.         mov   byte ptr es:[bx],0        // clear pixel
  42.         inc    bx
  43.         loop    col
  44.         dec    dx
  45.         cmp    dx,0
  46.         jz        cleanup
  47.         add    bx,hline                        // next row
  48.         sub    bx,d_blockx                    // screen back to start x
  49.         loop    row
  50.     }
  51.     cleanup:
  52.     asm {
  53.         pop    ds
  54.         pop    dx
  55.         pop    cx
  56.         pop    bx
  57.     }
  58.  
  59.  
  60. }
  61.  
  62. void BitMap::display (int scrx, int scry, int cntx, int cnty) {
  63.  
  64.     screnx=scrx;
  65.     screny=scry;
  66.  
  67.     int offbmp=FP_OFF(image_ptr)+(cntx*blockx)+(cnty*totalx*blocky);
  68.     int segbmp=FP_SEG(image_ptr);
  69.  
  70.     int d_blockx=blockx;
  71.     int d_blocky=blocky;
  72.     int d_totalx=totalx;
  73.  
  74.     int hline=maxx;                // set from Gscreen's maxx
  75.     int offscr=scrx+(scry*hline);
  76.  
  77.     wait_for_vbl();
  78.     asm {
  79.         push    ax
  80.         push    bx
  81.         push    cx
  82.         push    dx
  83.         push    ds
  84.         mov    dx,d_blocky                    // vertical count
  85.         push    0a000h                        // video memory segment
  86.         pop    es
  87.         mov    di,offscr                    // di to upper left of screen
  88.         push    segbmp                        // bitmap memory segment
  89.         pop    ds
  90.         mov    si,offbmp                    // si to upper left of bitmap
  91.         cld                                    // clear direction flag
  92.     }
  93.     row:
  94.     asm {
  95.         mov    cx,d_blockx                    // horizontal count
  96.         rep    movsb                            // write pixel row
  97.         dec    dx
  98.         cmp    dx,0
  99.         jz        cleanup
  100.         add    di,hline                        // next row
  101.         sub    di,d_blockx                    // screen back to start x
  102.         add    si,d_totalx                    // bmp back to next row
  103.         sub    si,d_blockx                    // bmp back to start x
  104.         loop    row
  105.     }
  106.     cleanup:
  107.     asm {
  108.         pop    ds
  109.         pop    dx
  110.         pop    cx
  111.         pop    bx
  112.         pop    ax
  113.     }
  114.  
  115. }
  116.  
  117. Gscreen::Gscreen (int md, int mx, int my) {
  118.     maxx=(mx>0) ? mx : 320;            // default to 13h
  119.     maxy=(my>0) ? my : 200;
  120.     mode=(md>0) ? md : 0x13;
  121.  
  122.     setmode (mode);
  123. }
  124.  
  125. Gscreen::~Gscreen (void) {
  126.     setmode (3);
  127. }
  128.  
  129. void Gscreen::setmode(int mode)
  130. {
  131.     union REGS inregs, outregs;
  132.     struct SREGS segregs;
  133.  
  134.     inregs.h.ah = 0x00;
  135.     inregs.h.al = mode;
  136.     int86x(0x10, &inregs, &outregs, &segregs);
  137. }
  138.  
  139.  
  140. // *************************************************************************
  141. // UnpackPcx() unpacks the RLE encoded PCX data from a file if pcx != NULL,
  142. // or the source buffer if pcx==NULL, to the Dest buffer. Unpacks NumBytes
  143. // bytes of decompressed data. (max 64000) This is a pretty dumb routine.
  144. // It's fast, but it expects you to know the uncompressed size of the data
  145. // (the NumBytes parameter), and you have to do all of the file and buffer
  146. // set-up elsewhere. Basically it's a core decoding engine.
  147. // *************************************************************************
  148.  
  149.  
  150. const char far *Gscreen::unpackpcx(char *name) {
  151.  
  152.     FILE* pcx;
  153.  
  154.     unsigned int     bytes=0;       // counts unpacked bytes
  155.     unsigned char    c;             // byte being processed
  156.     unsigned int     runlen;        // length of packet
  157.     unsigned int num_bytes;
  158.  
  159.     if ((pcx=fopen (name,"rb"))==NULL) {
  160.         return NULL;
  161.     }
  162.  
  163.     pcxh = new pcx_hdr;
  164.     fread(pcxh, sizeof (pcx_hdr), 1, pcx);
  165.  
  166.     num_bytes = (pcxh->Xmax+1)*(pcxh->Ymax+1);
  167.     image_ptr= new char[num_bytes+1];
  168.     if (image_ptr==NULL) return NULL;            // can't alloc mem
  169.  
  170.     do {
  171.         // get a key byte from the file
  172.         c=fgetc(pcx);
  173.  
  174.         // check if it's a packet ( yes if two high bits set )
  175.         if ((c & 0xc0) == 0xc0)    {
  176.             // AND off the high bits
  177.             runlen = (c & 0x3f);
  178.             // get the next byte in the file
  179.             c=fgetc(pcx);
  180.             // repeat it runlen times
  181.             while(runlen--) (image_ptr[bytes++]=c);
  182.         }
  183.         else
  184.         // if not a packet just store the byte
  185.             image_ptr[bytes++]=c;
  186.     } while (bytes<num_bytes);
  187.     for (int i=0; i<(3*256); i++) colregs[i]=(getc(pcx) >> 2);
  188. //    setpalette();
  189.     return image_ptr;
  190. }
  191.  
  192. void Gscreen::display () {
  193.  
  194.     int offbmp=FP_OFF(image_ptr);
  195.     int segbmp=FP_SEG(image_ptr);
  196.  
  197.     int wd=pcxh->Xmax+1;
  198.     int hi=pcxh->Ymax+1;
  199.     int block=maxx;
  200.  
  201.     wait_for_vbl();
  202.     asm {
  203.         push    ax
  204.         push    bx
  205.         push    cx
  206.         push    dx
  207.         push    ds
  208.         mov    dx,hi                            // vertical count
  209.         push    0a000h                        // video memory segment
  210.         pop    es
  211.         mov    di,0                                // di to upper left of screen
  212.         push    segbmp                        // bitmap memory segment
  213.         pop    ds
  214.         mov    si,offbmp                        // si to upper left of bitmap
  215.         cld                                        // clear direction flag
  216.     }
  217.     row:
  218.     asm {
  219.         mov    cx,wd                                // horizontal count
  220.         rep    movsb                                // write pixel row
  221.         dec    dx
  222.         cmp    dx,0
  223.         jz        cleanup
  224.         add    di,block                            // next row
  225.         sub    di,wd                                // back to start x
  226.         loop    row
  227.     }
  228.     cleanup:
  229.     asm {
  230.         pop    ds
  231.         pop    dx
  232.         pop    cx
  233.         pop    bx
  234.         pop    ax
  235.     }
  236. }
  237.  
  238. void Gscreen::setpalette(void) {
  239.     int    offcol,segcol;
  240.  
  241.     offcol=FP_OFF(colregs);
  242.     segcol=FP_SEG(colregs);
  243.     asm{
  244.         mov    dx,es
  245.         push    dx
  246.         mov    dx,segcol
  247.         mov    es,dx
  248.         mov    ah,10h
  249.         mov    al,12h
  250.         mov    bx,0
  251.         mov    cx,100h
  252.         mov    dx,offcol
  253.         int    10h
  254.         pop    dx
  255.         mov    es,dx
  256.     }
  257. }
  258.  
  259.  
  260. void Gscreen::wait_for_vbl(void)
  261. {
  262.     while ((inport(0x3da)&8)==0);
  263. }
  264.  
  265. void BitMap::wait_for_vbl(void)
  266. {
  267.     while ((inport(0x3da)&8)==0);
  268. }
  269.  
  270.  
  271. #endif
  272.