Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

basegfx.cpp

Go to the documentation of this file.
00001 
00005 /*
00006     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00007     Copyright (C) 1994-2005  Martin Bickel  and  Marc Schellenberger
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program; see the file COPYING. If not, write to the
00021     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00022     Boston, MA  02111-1307  USA
00023 */
00024 
00025 #include <cstring>
00026 #include <cstdlib>
00027 #include <math.h>
00028 #include "global.h"
00029 #include "basegfx.h"
00030 #include "newfont.h"
00031 #include "misc.h"
00032 
00033 #ifdef _DOS_
00034  #include "dos/vesa.h"
00035 #else
00036  #include "sdl/graphics.h"
00037 #endif
00038 
00039 tgraphmodeparameters *agmp = (tgraphmodeparameters *) & activegraphmodeparameters;
00040 tgraphmodeparameters *hgmp = (tgraphmodeparameters *) & hardwaregraphmodeparameters;
00041 
00042 int xlatbuffersize = 66000;
00043 
00044 void generategrayxlattable( ppixelxlattable tab, char offset, char size, dacpalette256* pal )
00045 {
00046         for ( int b = 0; b <= 255; b++) {
00047 //              (*tab)[b] = (char) (offset + size - 1 - ((*activepalette256)[b][0] + (*activepalette256)[b][1] + (*activepalette256)[b][2]) * size / 192);
00048                 (*tab)[b] = (char) (offset + size - 1 - ( 0.299 * (*pal)[b][0] + 0.587 * (*pal)[b][1] + 0.114 * (*pal)[b][2]) * size / 64 );
00049         }
00050 }
00051 
00052 void getpicsize( void* hd2, int &width, int &height)
00053 {
00054    trleheader* hd = (trleheader*) hd2;
00055    if (hd->id == 16973) {
00056       width = hd->x;
00057       height = hd->y;
00058    } else {
00059      width = hd->id + 1;
00060      height = hd->size + 1;
00061    }
00062 }
00063 
00064 int getpicsize2( void* hd2 )
00065 {
00066    trleheader* hd = (trleheader*) hd2;
00067    int width; 
00068    int height;
00069    if (hd->id == 16973) 
00070       return hd->size + sizeof(*hd);
00071    else {
00072      width = hd->id + 1;
00073      height = hd->size + 1;
00074      return height*width+4;
00075    }
00076 }
00077 
00078 
00079 
00080 
00081 void 
00082 rahmen(bool invers,
00083        int x1,
00084        int y1,
00085        int x2,
00086        int y2)
00087 {
00088         collategraphicoperations cgo ( x1, y1, x2, y2 );
00089         int col =       (invers == false)       ?       white   :       darkgray;
00090 
00091         line(x1, y1, x1, y2, col);
00092         line(x1, y1, x2, y1, col);
00093         
00094         col     =               (invers == true)        ?       white   :       darkgray;
00095         line(x2, y1, x2, y2, col);
00096         line(x1, y2, x2, y2, col);
00097 }
00098 
00099 void tdrawline :: start ( int x1, int y1, int x2, int y2 )
00100 { 
00101    int      i, deltax, deltay, numpixels, d, dinc1, dinc2, x, xinc1, xinc2, y, yinc1, yinc2; 
00102 
00103 
00104     /*  calculate deltax and deltay for initialisation  */ 
00105     
00106   deltax = x2 - x1; 
00107   if ( deltax < 0 )
00108      deltax = -deltax;
00109 
00110   deltay = y2 - y1; 
00111   if ( deltay < 0 )
00112      deltay = -deltay;
00113 
00114     /*  initialize all vars based on which is the independent variable  */ 
00115   if (deltax >= deltay) 
00116     { 
00117 
00118         /*  x is independent variable  */ 
00119       numpixels = deltax + 1; 
00120       d = (2 * deltay) - deltax; 
00121       dinc1 = deltay << 1; 
00122       dinc2 = (deltay - deltax) << 1; 
00123       xinc1 = 1; 
00124       xinc2 = 1; 
00125       yinc1 = 0; 
00126       yinc2 = 1; 
00127     } 
00128   else 
00129     { 
00130 
00131         /*  y is independent variable  */ 
00132       numpixels = deltay + 1; 
00133       d = (2 * deltax) - deltay; 
00134       dinc1 = deltax << 1; 
00135       dinc2 = (deltax - deltay) << 1; 
00136       xinc1 = 0; 
00137       xinc2 = 1; 
00138       yinc1 = 1; 
00139       yinc2 = 1; 
00140     } 
00141 
00142     /*  make sure x and y move in the right directions  */ 
00143   if (x1 > x2) 
00144     { 
00145       xinc1 = -xinc1; 
00146       xinc2 = -xinc2; 
00147     } 
00148   if (y1 > y2) 
00149     { 
00150       yinc1 = -yinc1; 
00151       yinc2 = -yinc2; 
00152     } 
00153 
00154     /*  start drawing at <x1, y1>  */ 
00155   x = x1; 
00156   y = y1; 
00157 
00158     /*  draw the pixels  */ 
00159   for (i = 1; i <= numpixels; i++) 
00160     { 
00161       putpix( x, y ); 
00162 
00163 
00164       if (d < 0) 
00165         { 
00166           d = d + dinc1; 
00167           x = x + xinc1; 
00168           y = y + yinc1; 
00169         } 
00170       else 
00171         { 
00172           d = d + dinc2; 
00173           x = x + xinc2; 
00174           y = y + yinc2; 
00175         } 
00176     } 
00177 } 
00178 
00179 
00180 void 
00181 line(int  x1,
00182      int  y1,
00183      int  x2,
00184      int  y2,
00185      char actcol)
00186 {
00187    collategraphicoperations cgs ( x1, y1, x2, y2 );
00188         float           m, b;
00189         int             w;
00190         float           yy1, yy2, xx1, xx2;
00191 
00192 
00193 
00194     if ( x1 == x2) {
00195         for (w=y1;w<=y2 ;w++ ) 
00196            putpixel(x1, w, actcol );
00197 
00198     } else {
00199        if ( y1 == y2) {
00200           for (w=x1;w<=x2 ;w++ ) 
00201                putpixel(w, y1, actcol );
00202        } else {
00203                 yy1 = y1;
00204                 yy2 = y2;
00205                 xx1 = x1;
00206                 xx2 = x2;
00207                 m = (yy2 - yy1) / (xx2 - xx1);
00208                 b = y1 - m * x1;
00209                 if ((m <= 1) && (m >= -1)) {
00210                         if (x2 < x1) {
00211                                 w = x2;
00212                                 x2 = x1;
00213                                 x1 = w;
00214                                 w = y2;
00215                                 y2 = y1;
00216                                 y1 = w;
00217                         }
00218                         for (w = x1; w <= x2; w++) 
00219                                 putpixel(w, (int) (m * w + b), actcol);
00220                         
00221                 } else {
00222                         if (y2 < y1) {
00223                                 w = x2;
00224                                 x2 = x1;
00225                                 x1 = w;
00226                                 w = y2;
00227                                 y2 = y1;
00228                                 y1 = w;
00229                         }
00230                         for (w = y1; w <= y2; w++) {
00231                                 putpixel((int) ((w - b) / m), w, actcol);
00232                         }
00233         
00234                 }
00235          } /* endif */
00236      }
00237 
00238 }
00239 
00240 void 
00241 xorline(int  x1,
00242      int  y1,
00243      int  x2,
00244      int  y2,
00245      char actcol)
00246 {
00247    collategraphicoperations cgs ( x1, y1, x2, y2 );
00248 
00249         float           m, b;
00250         int             w;
00251         float           yy1, yy2, xx1, xx2;
00252 
00253     if ( x1 == x2) {
00254         for (w=y1;w<=y2 ;w++ ) {
00255                 putpixel( x1, w, getpixel ( x1, w ) ^ actcol);
00256         } /* endfor */
00257     } else {
00258         yy1 = y1;
00259         yy2 = y2;
00260         xx1 = x1;
00261         xx2 = x2;
00262         m = (yy2 - yy1) / (xx2 - xx1);
00263         b = y1 - m * x1;
00264         if ((m <= 1) && (m >= -1)) {
00265                 if (x2 < x1) {
00266                         w = x2;
00267                         x2 = x1;
00268                         x1 = w;
00269                         w = y2;
00270                         y2 = y1;
00271                         y1 = w;
00272                 }
00273                 for (w = x1; w <= x2; w++) {
00274                         putpixel(w, (int) (m * w + b), getpixel( w, (int) (m * w + b) ) ^ actcol);
00275                 }
00276         } else {
00277                 if (y2 < y1) {
00278                         w = x2;
00279                         x2 = x1;
00280                         x1 = w;
00281                         w = y2;                  
00282                         y2 = y1;
00283                         y1 = w;
00284                 }
00285                 for (w = y1; w <= y2; w++) {
00286                         putpixel((int) ((w - b) / m), w, getpixel ( (int) ((w - b) / m), w ) ^ actcol);             
00287                 }
00288 
00289         }
00290      }
00291 
00292 }
00293 
00294 
00295 
00296 void 
00297 rectangle(int x1,
00298           int y1,
00299           int x2,
00300           int y2,
00301           char color)
00302 {
00303    collategraphicoperations cgs ( x1, y1, x2, y2 );
00304 
00305         line(x1, y1, x1, y2, color);
00306         line(x1, y1, x2, y1, color);
00307         line(x2, y1, x2, y2, color);
00308         line(x1, y2, x2, y2, color);
00309 
00310 }
00311 
00312 
00313 void xorrectangle(int x1,
00314              int y1,
00315              int x2,
00316              int y2,
00317              char color)
00318 {
00319    collategraphicoperations cgs ( x1, y1, x2, y2 );
00320 
00321           xorline(x1,y1,x1,y2,color); 
00322           xorline(x1,y1,x2,y1,color);
00323           xorline(x2,y1,x2,y2,color); 
00324           xorline(x1,y2,x2,y2,color);
00325 
00326 }
00327 
00328 /*
00329 void         xorrectangle( tmouserect r, byte         color)
00330 {
00331    xorrectangle ( r.x1, r.y1, r.x2, r.y2, color );
00332 }
00333 
00334   */
00335 
00336 
00337 void* halfpict ( void* vbuf )
00338 {
00339    char* buf = (char*) vbuf;
00340 
00341    Uint16* wp = (Uint16*) xlatbuffer;
00342    char* dest = (char*) xlatbuffer;
00343 
00344    trleheader*   hd = (trleheader*) vbuf; 
00345 
00346    if ( hd->id == 16973 ) { 
00347       wp[0] = hd->x / 2;
00348       wp[1] = hd->y / 2;
00349 
00350       if ( ( wp[0] + 1 ) * ( wp[1] + 1 ) + 4 >= xlatbuffersize )
00351          throw fatalgraphicserror ( "halfpict : picture larger than buffer ! " );
00352 
00353       dest += 4;
00354 
00355       buf += sizeof ( *hd );
00356 
00357 
00358       int linecount = 0;
00359       int rowcount = 0;
00360 
00361       for ( int c = 0; c < hd->size; c++ ) {
00362          if ( *buf == hd->rle ) {
00363             for ( int i = buf[1]; i > 0; i-- ) {
00364                if ( !(linecount & 1)  &&  !(rowcount & 1)) {
00365                   *dest = buf[2];
00366                   dest++;
00367                }
00368                rowcount++;
00369                if ( rowcount > hd->x ) {
00370                   rowcount = 0;
00371                   linecount++;
00372                }
00373             }
00374 
00375             buf += 3;
00376             c += 2;
00377 
00378          } else {
00379             if ( !(linecount & 1)  &&  !(rowcount & 1)) {
00380                *dest = *buf;
00381                dest++;
00382             }
00383             buf++;
00384             rowcount++;
00385             if ( rowcount > hd->x ) {
00386                rowcount = 0;
00387                linecount++;
00388             }
00389          }
00390          if ( (PointerSizedInt)dest - (PointerSizedInt)xlatbuffer > xlatbuffersize )
00391             throw fatalgraphicserror ( "halfpict : picture larger than buffer ! " );
00392 
00393       }
00394    } else {
00395       int linecount = 0;
00396       int rowcount = 0;
00397 
00398       Uint16* wp2 = (Uint16*) vbuf;
00399 
00400       wp[0] = wp2[0] / 2;
00401       wp[1] = wp2[1] / 2;
00402 
00403       if ( ( wp[0] + 1 ) * ( wp[1] + 1 ) + 4 >= xlatbuffersize )
00404          throw fatalgraphicserror ( "halfpict : picture larger than buffer ! " );
00405 
00406       dest += 4;
00407       buf += 4;
00408 
00409       for ( int c = (wp2[0] + 1) * (wp2[1] + 1); c > 0; c-- ) {
00410          if ( !(linecount & 1)  &&  !(rowcount & 1)) {
00411             *dest = *buf;
00412             dest++;
00413          }
00414          buf++;
00415          rowcount++;
00416          if ( rowcount > wp2[0] ) {
00417             rowcount = 0;
00418             linecount++;
00419          }
00420       }
00421 
00422    }
00423    return xlatbuffer;
00424 } 
00425 
00426 #if 0
00427 void putshadow ( int x1, int y1, void* ptr, ppixelxlattable xl )
00428 {
00429    Uint16* w = (Uint16*) ptr;
00430    char* c = (char*) ptr + 4;
00431    int spacelength = agmp->scanlinelength - *w - 1;
00432 
00433    collategraphicoperations cgo ( x1, y1, x1 + w[0], y1+w[1] );
00434    if ( agmp->windowstatus == 100 ) {
00435       char* buf = (char*) (agmp->scanlinelength * y1 + x1 + agmp->linearaddress);
00436       for ( int y = w[1] + 1; y > 0; y-- ) {
00437          for ( int x = w[0]+1; x > 0; x-- ) {
00438             if ( *c != 255 )
00439                *buf = (*xl)[*buf];
00440             buf++;
00441             c++;
00442          }
00443          buf+=spacelength;
00444       }
00445    }
00446 
00447 }
00448 #endif
00449 void putpicturemix ( int x1, int y1, void* ptr, int rotation, char* mixbuf )
00450 {
00451    Uint16* w = (Uint16*) ptr;
00452    char* c = (char*) ptr + 4;
00453    int spacelength = agmp->scanlinelength - *w - 1;
00454 
00455    collategraphicoperations cgo ( x1, y1, x1 + w[0], y1+w[1] );
00456    if ( agmp->windowstatus == 100 ) {
00457       char* buf = (char*) (agmp->scanlinelength * y1 + x1 + agmp->linearaddress);
00458       for ( int y = w[1] + 1; y > 0; y-- ) {
00459          for ( int x = w[0]+1; x > 0; x-- ) {
00460             if ( *c != 255 ) {
00461                int o = *buf << 8;
00462                if ( *c >= 16  && *c < 24 )
00463                   *buf = mixbuf[o + *c + rotation];
00464                else
00465                   *buf = mixbuf[o + *c];
00466             }
00467             buf++;
00468             c++;
00469          }
00470          buf+=spacelength;
00471       }
00472    }
00473 
00474 }
00475 
00476 
00477 void putinterlacedrotimage ( int x1, int y1, void* ptr, int rotation )
00478 {
00479    Uint16* w = (Uint16*) ptr;
00480    char* c = (char*) ptr + 4;
00481    int spacelength = agmp->scanlinelength - *w - 1;
00482 
00483    collategraphicoperations cgo ( x1, y1, x1 + w[0], y1+w[1] );
00484    if ( agmp->windowstatus == 100 ) {
00485       char* buf = (char*) (agmp->scanlinelength * y1 + x1 + agmp->linearaddress);
00486       for ( int y = w[1] + 1; y > 0; y-- ) {
00487          for ( int x = w[0]+1; x > 0; x-- ) {
00488             if ( *c != 255 ) {
00489                if ( ((PointerSizedInt)(buf+y)) & 1 ) {
00490                   if ( *c >= 16  && *c < 24 )
00491                      *buf = *c + rotation;
00492                   else
00493                      *buf = *c;
00494                }
00495             }
00496             buf++;
00497             c++;
00498          }
00499          buf+=spacelength;
00500       }
00501    }
00502 
00503 }
00504 
00505 
00506 void rotatepict90 ( void* s, void* d )
00507 {
00508    Uint16* sw = (Uint16*) s;
00509    char* sc = (char*) s + 4;
00510    
00511    Uint16* dw = (Uint16*) d;
00512    char* dc = (char*) d + 4;
00513 
00514    dw[0] = sw[1];
00515    dw[1] = sw[0];
00516 
00517    int dl = dw[0]+1;
00518 //   int dh = dw[1]+1;
00519 
00520    int sl = sw[0]+1;
00521    int sh = sw[1]+1;
00522 
00523    for (int y = 0; y <= dw[1]; y++) 
00524      for (int x = 0; x <= dw[0]; x++) 
00525          dc[ y * dl + x] = sc[ ( sh - x - 1 ) * sl + y];
00526 }
00527   union tpix {
00528   struct { char r,g,b,a; } s;
00529   int all;
00530 };
00531 
00532 
00533 typedef tpix timage[ 100 ][ 100 ];
00534 
00535 int getimagepixel ( void* image, int x, int y )
00536 {
00537    int xs, ys;
00538    getpicsize ( image, xs, ys );
00539 
00540 
00541    y += ys/2;
00542    x += xs/2;
00543    if ( x < 0  || x >= xs || y < 0 || y >= ys )
00544       return -1;
00545    else {
00546       char* pc = (char*) image;
00547       return pc[ 4 + y * xs + x];
00548    }
00549 }
00550 
00551 const float pi = 3.14159265;
00552 
00553 char* rotatepict ( void* image, int organgle )
00554 {
00555    int fieldxsize, fieldysize;
00556    getpicsize(image, fieldxsize, fieldysize );
00557 
00558    float angle = ((float)organgle) / 360 * 2 * pi + pi;
00559 
00560    char* dst = new char[ imagesize ( 0, 0, fieldxsize, fieldysize ) ];
00561    Uint16* wp = (Uint16*) dst;
00562    wp[0] = fieldxsize-1;
00563    wp[1] = fieldysize-1;
00564 
00565    char* pnt  = dst + 4;
00566 
00567    for ( int y = 0; y < fieldysize; y++ ) {
00568       for ( int x = 0; x < fieldxsize; x++ ) {
00569          int dx = x - fieldxsize/2 ;
00570          int dy = fieldysize/2 - y;
00571          double nx = 0;
00572          double ny = 0;
00573          if ( organgle != 0 && organgle != -180 && organgle != 180) {
00574             float wnk ;
00575             if ( dx  )
00576                wnk = atan2 ( double(dy), double(dx) );
00577             else
00578                if ( dy > 0 )
00579                   wnk = pi/2;
00580                else
00581                   wnk = -pi/2;
00582 
00583             wnk -= angle;
00584             float radius = sqrt ( double(dx * dx + dy * dy ));
00585 
00586             nx = radius * cos ( wnk );
00587             ny = radius * sin ( wnk );
00588          } else
00589             if ( organgle == 0 ) {
00590                nx = -dx;
00591                ny = -dy;
00592             } else
00593                if ( organgle == 180 || organgle == -180) {
00594                   nx = dx;
00595                   ny = dy;
00596                }
00597 
00598 
00599          int newpix = getimagepixel ( image, (int)-nx, (int)ny );
00600          if ( newpix == -1 )
00601             *pnt = 255;
00602          else
00603             *pnt = newpix;
00604 
00605          pnt++;
00606       }
00607    }
00608 
00609    return dst;
00610 }
00611 
00612 
00613 char* rotatepict_grw ( void* image, int organgle )
00614 {
00615    int fieldxsize, fieldysize;
00616    getpicsize(image, fieldxsize, fieldysize );
00617 
00618    float angle = ((float)organgle) / 360 * 2 * pi + pi;
00619 
00620    int d = int(sqrt(double(fieldxsize*fieldxsize + fieldysize*fieldysize )));
00621 
00622    char* dst = new char[ imagesize ( 0, 0, d,d ) ];
00623    Uint16* wp = (Uint16*) dst;
00624    wp[0] = d-1;
00625    wp[1] = d-1;
00626 
00627    char* pnt  = dst + 4;
00628 
00629    for ( int y = 0; y < d; y++ ) {
00630       for ( int x = 0; x < d; x++ ) {
00631          int dx = x - d/2 ;
00632          int dy = d/2 - y;
00633          float nx = 0;
00634          float ny = 0;
00635          if ( organgle != 0 && organgle != -180 && organgle != 180) {
00636             float wnk ;
00637             if ( dx  )
00638                wnk = atan2 ( double(dy), double(dx) );
00639             else
00640                if ( dy > 0 )
00641                   wnk = pi/2;
00642                else
00643                   wnk = -pi/2;
00644 
00645             wnk -= angle;
00646             float radius = sqrt ( double(dx * dx + dy * dy ));
00647 
00648             nx = radius * cos ( wnk );
00649             ny = radius * sin ( wnk );
00650          } else
00651             if ( organgle == 0 ) {
00652                nx = -dx;
00653                ny = -dy;
00654             } else
00655                if ( organgle == 180 || organgle == -180) {
00656                   nx = dx;
00657                   ny = dy;
00658                }
00659 
00660 
00661          int newpix = getimagepixel ( image, (int)-nx, (int)ny );
00662          if ( newpix == -1 )
00663             *pnt = 255;
00664          else
00665             *pnt = newpix;
00666 
00667          pnt++;
00668       }
00669    }
00670 
00671    return dst;
00672 }
00673 
00674 
00675 void flippict ( void* s, void* d, int dir )
00676 {
00677    Uint16* sw = (Uint16*) s;
00678    char* sc = (char*) s + 4;
00679    
00680    Uint16* dw = (Uint16*) d;
00681    char* dc = (char*) d + 4;
00682 
00683    dw[1] = sw[1];
00684    dw[0] = sw[0];
00685 
00686    int sl = sw[0]+1;
00687    int sh = sw[1]+1;
00688 
00689    if ( dir == 1 ) {
00690       for (int y = 0; y <= dw[1]; y++) 
00691         for (int x = 0; x <= dw[0]; x++) 
00692             dc[ y * sl + x] = sc[ y * sl + ( sl - 1 - x ) ];
00693    } else {
00694       for (int y = 0; y <= dw[1]; y++) 
00695         for (int x = 0; x <= dw[0]; x++) 
00696             dc[ y * sl + x] = sc[ ( sh - 1 - y)  * sl + x ];
00697    }
00698 }
00699 
00700 
00701 
00702 
00703 void putpixel8 ( int x1, int y1, int color )
00704 {
00705     collategraphicoperations cgo ( x1, y1, x1, y1 );
00706     char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
00707     *buf = color;
00708 }
00709 
00710 int getpixel8 ( int x1, int y1 )
00711 {
00712     char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
00713     return *buf;
00714 }
00715 
00716 
00717 void putpixel(int x1, int y1, int color)
00718 {
00719    collategraphicoperations cgo ( x1, y1, x1, y1 );
00720    if ( agmp->byteperpix == 1 )
00721       putpixel8 ( x1, y1, color );
00722    else {
00723       if ( agmp->windowstatus == 100 ) {
00724          char* pc = (char*) ( agmp->linearaddress + x1 * agmp->byteperpix + y1 * agmp->scanlinelength );
00725          int alpha = color >> 24;
00726          if ( alpha == 0 ) {
00727             pc[ agmp->redfieldposition/8 ] = color & 0xff;
00728             pc[ agmp->greenfieldposition/8 ] = (color >> 8) & 0xff;
00729             pc[ agmp->bluefieldposition/8 ] = (color >> 16) & 0xff;
00730          } else {
00731             pc[ agmp->redfieldposition/8 ] = pc[ agmp->redfieldposition/8 ] * alpha / alphabase + (color & 0xff) * (alphabase - alpha ) / alphabase;
00732             pc[ agmp->greenfieldposition/8 ] = pc[ agmp->greenfieldposition/8 ] * alpha / alphabase + ((color >> 8 ) & 0xff) * (alphabase - alpha ) / alphabase;
00733             pc[ agmp->bluefieldposition/8 ] = pc[ agmp->bluefieldposition/8 ] * alpha / alphabase + ((color >> 16) & 0xff) * (alphabase - alpha ) / alphabase;
00734          }
00735       } else {
00736         /*
00737          int pos = x1 * agmp->byteperpix + y1 * agmp->scanlinelength;
00738          int page = pos >> 16;
00739          if ( hgmp->actsetpage != page )
00740             setvirtualpagepos ( page );
00741 
00742          char* pc = (char*) ( agmp->linearaddress + (pos & 0xffff) );
00743 
00744          int alpha = color >> 24;
00745          if ( alpha == 0 ) {
00746             pc[ agmp->redfieldposition/8 ] = color & 0xff;
00747             pc[ agmp->greenfieldposition/8 ] = (color >> 8) & 0xff;
00748             pc[ agmp->bluefieldposition/8 ] = (color >> 16) & 0xff;
00749          } else {
00750             pc[ agmp->redfieldposition/8 ] = pc[ agmp->redfieldposition/8 ] * alpha / alphabase + (color & 0xff) * (alphabase - alpha ) / alphabase;
00751             pc[ agmp->greenfieldposition/8 ] = pc[ agmp->greenfieldposition/8 ] * alpha / alphabase + ((color >> 8 ) & 0xff) * (alphabase - alpha ) / alphabase;
00752             pc[ agmp->bluefieldposition/8 ] = pc[ agmp->bluefieldposition/8 ] * alpha / alphabase + ((color >> 16) & 0xff) * (alphabase - alpha ) / alphabase;
00753          }
00754         */ 
00755       }
00756    }
00757 
00758 }
00759 
00760 int getpixel(int x1, int y1)
00761 {
00762    if ( agmp->byteperpix == 1 )
00763       return getpixel8( x1, y1 );
00764    else {
00765       if ( agmp->windowstatus == 100 ) {
00766          char* pc = (char*) ( agmp->linearaddress + x1 * agmp->byteperpix + y1 * agmp->scanlinelength );
00767          trgbpixel pix;
00768          pix.channel.r = pc[ agmp->redfieldposition/8 ];
00769          pix.channel.g = pc[ agmp->greenfieldposition/8 ];
00770          pix.channel.b = pc[ agmp->bluefieldposition/8 ];
00771          pix.channel.a = 0;
00772          return pix.rgb;
00773       } else {
00774         return -1;
00775       }
00776    }
00777 }
00778 
00779 
00780 
00781 
00782 TrueColorImage :: TrueColorImage ( int x, int y )
00783 {
00784    pix = new trgbpixel[x*y];
00785    xsize = x;
00786    ysize = y;
00787 }
00788 
00789 TrueColorImage :: ~TrueColorImage (  )
00790 {
00791    if ( pix ) {
00792       delete[] pix;
00793       pix = NULL;
00794    }
00795 }
00796 
00797 
00798 int getpixelfromimage ( void* buf, int x, int y )
00799 {
00800    Uint16* wp = (Uint16*) buf;
00801    if ( x > wp[0]  ||  y > wp[1] || x < 0 || y < 0 )
00802       return -1;
00803 
00804    char* pc = (char*) buf;
00805    return pc[4 + x + y * (wp[0]+1) ];
00806 }
00807 
00808 void TrueColorImage :: setpix ( int x, int y, int r, int g, int b, int alpha )
00809 {
00810    trgbpixel* p = & pix[ x + y * xsize ];
00811    p->channel.r = r;
00812    p->channel.g = g;
00813    p->channel.b = b;
00814    p->channel.a = alpha;
00815 }
00816 
00817 void TrueColorImage :: setpix ( int x, int y, const trgbpixel& _pix )
00818 {
00819    pix[ x + y * xsize ] = _pix;
00820 }
00821 
00822 
00823 trgbpixel TrueColorImage :: getpix ( int x, int y )
00824 {
00825    return pix[ x + y * xsize ];
00826 }
00827 
00828 
00829 int TrueColorImage :: getxsize( void )
00830 {
00831    return xsize;
00832 }
00833 
00834 int TrueColorImage :: getysize( void )
00835 {
00836    return ysize;
00837 }
00838 
00839 
00840 
00841 #define f2i(x) (int(x))
00842 #define f2i2(x) (int(x+0.5))
00843 
00844 
00845 int newpalgenerated = 0;
00846 dacpalette256 ppal;
00847 
00848 
00849 
00850 
00851 TrueColorImage* zoomimage ( void* buf, int xsize, int ysize, dacpalette256 pal, int interpolate, int proportional )
00852 {
00853    if ( !newpalgenerated ) 
00854       for ( int i = 0; i < 256; i++ )
00855          for ( int j = 0; j<3; j++ )
00856             ppal[i][j] = pal[i][j] << 2;
00857 
00858 
00859 
00860    int orgx;
00861    int orgy;
00862    getpicsize ( buf, orgx, orgy );
00863 
00864    {
00865       float ratiox = (float)xsize / (float)orgx;
00866       float ratioy = (float)ysize / (float)orgy;
00867       if ( proportional ) {
00868          if ( ratiox > ratioy )
00869             xsize = (int) (ratioy * orgx);
00870          else
00871             ysize = (int) (ratiox * orgy);
00872       }
00873    }
00874 
00875    TrueColorImage* img = new TrueColorImage ( xsize, ysize );
00876    
00877 
00878    float dx = (float)orgx / (float)xsize;
00879    float dy = (float)orgy / (float)ysize;
00880 
00881    float oy = 0;
00882    for ( int y = 0; y < ysize; y++, oy+=dy ) {
00883 
00884       int oyi = f2i ( oy );
00885       float oyif = oyi;
00886 
00887       float ox = 0;
00888       for ( int x = 0; x < xsize; x++,ox+=dx ) {
00889 
00890          float r = 0;
00891          float g = 0;
00892          float b = 0;
00893          float alpha = 0;
00894 
00895          if ( interpolate ) {
00896             float d;
00897 
00898             int oxi = f2i ( ox );
00899             float oxif = oxi;
00900    
00901             float dist = 0;
00902             int alphanum = 0;
00903 
00904             // pixel links oben
00905             int px1 = getpixelfromimage ( buf, oxi, oyi );
00906             int px2 = getpixelfromimage ( buf, oxi+1, oyi );
00907             int px3 = getpixelfromimage ( buf, oxi, oyi+1 );
00908             int px4 = getpixelfromimage ( buf, oxi+1, oyi+1 );
00909             if ( px1 == 255 && px2 == 255 && px3 == 255 && px4 == 255 ) {
00910                 r = 0;
00911                 g = 0;
00912                 b = 0;
00913                 alpha = alphabase;
00914             } else {
00915 
00916                if ( px1 >= 0 ) {
00917                   d = ( 1-(ox - oxif)) * ( 1-( oy - oyif ));
00918       
00919                   if ( px1 == 255 ) {
00920                      alpha += ((float)alphabase) * d;
00921                      alphanum++;
00922                   }
00923                   else {
00924                      dist += d;
00925                      r += ppal[px1][0] * d ;
00926                      g += ppal[px1][1] * d ;
00927                      b += ppal[px1][2] * d ;
00928                   }
00929                }
00930                   
00931                // pixel rechts oben
00932                if ( px2 >= 0 ) {
00933                   d = (ox - oxif) * ( 1 -  ( oy - oyif ));
00934       
00935                   if ( px2 == 255 ) {
00936                      alpha += ((float)alphabase) * d;
00937                      alphanum++;
00938                   }
00939                   else {
00940                      dist += d;
00941                      r += ppal[px2][0] * d ;
00942                      g += ppal[px2][1] * d ;
00943                      b += ppal[px2][2] * d ;
00944                   }
00945                }
00946    
00947    
00948                // pixel links unten
00949                if ( px3 >= 0 ) {
00950                   d = ( 1- (ox - oxif)) *  (oy - oyif);
00951       
00952                   if ( px3 == 255 ) {
00953                      alpha += ((float)alphabase) * d;
00954                      alphanum++;
00955                   }
00956                   else {
00957                      dist += d;
00958                      r += ppal[px3][0] * d ;
00959                      g += ppal[px3][1] * d ;
00960                      b += ppal[px3][2] * d ;
00961                   }
00962                }
00963    
00964                // pixel rechts unten
00965                if ( px4 >= 0 ) {
00966                   d = (ox - oxif) *  (oy - oyif);
00967       
00968                   if ( px4 == 255 ) {
00969                      alpha += ((float)alphabase) * d;
00970                      alphanum++;
00971                   }
00972                   else {
00973                      dist += d;
00974                      r += ppal[px4][0] * d ;
00975                      g += ppal[px4][1] * d ;
00976                      b += ppal[px4][2] * d ;
00977                   }
00978                }
00979    
00980                if ( alphanum <= 2 ) 
00981                   alpha = 0;
00982    
00983                if ( dist ) {
00984                   r /= dist;
00985                   g /= dist;
00986                   b /= dist;
00987                   alpha /= dist;
00988                } else {
00989                   r = 0;
00990                   g = 0;
00991                   b = 0;
00992                   alpha = alphabase;
00993                }
00994             }
00995          } else {
00996              int px = getpixelfromimage ( buf, f2i2(ox-0.01), f2i2(oy-0.01) );
00997              if ( px == 255 ) 
00998                 alpha += alphabase ;
00999              else {
01000                 r += ppal[px][0] ;
01001                 g += ppal[px][1] ;
01002                 b += ppal[px][2] ;
01003              }
01004 
01005          }
01006          img->setpix ( x, y, f2i(r), f2i(g), f2i(b), f2i(alpha) );
01007       }
01008    }
01009    
01010    return img;
01011 }
01012 
01013 
01014 TrueColorImage* smoothimage ( TrueColorImage* src )
01015 {
01016   TrueColorImage* dst = new TrueColorImage ( src->getxsize(), src->getysize() );
01017   for ( int y = 0; y < src->getysize(); y++ )
01018      for ( int x = 0; x < src->getxsize(); x++ ) {
01019         if ( src->getpix ( x, y ).channel.a < alphabase / 2 ) {
01020            int cnt = 0;
01021            int r = 0;
01022            int g = 0;
01023            int b = 0;
01024            for ( int a = -1; a <= 1; a++ )
01025               for ( int bb = -1; bb <= 1; bb++ ) {
01026                   int nx = x+a;
01027                   int ny = y+bb;
01028                   if ( nx >= 0 && ny >= 0 && nx < src->getxsize() && ny < src->getysize()) {
01029                      trgbpixel p = src->getpix( nx, ny );
01030                      if ( p.channel.a < alphabase/2 ) {
01031                         cnt++;
01032                         r += p.channel.r;
01033                         g += p.channel.g;
01034                         b += p.channel.b;
01035                      }
01036                   }
01037               }
01038 
01039            dst->setpix ( x, y, r/cnt, g/cnt, b/cnt, 0 );
01040         } else {
01041            dst->setpix ( x, y, 0, 0, 0, alphabase );
01042         }
01043      }
01044   return dst;
01045 }
01046 
01047 #define sqr(a) (a)*(a)
01048 #define cub(a) abs ((a)*(a)*(a))
01049 
01050 
01051 #ifndef minimal
01052  #include "basestrm.h"
01053 #endif
01054 
01055 
01056 TrueColorImage* convertimage2tc ( void* buf, dacpalette256 pal )
01057 {
01058    if ( !buf ) 
01059       return NULL;
01060 
01061    int x, y;
01062    getpicsize ( buf, x, y );
01063    return zoomimage ( buf, x,y , pal, 0, 0 );
01064 }
01065 
01066 int
01067 imagesize(int x1, int y1, int x2, int y2)
01068 {
01069         return ((x2 - x1 + 1) * (y2 - y1 + 1) + 4);
01070 }
01071 
01072 #if 0
01073 char* convertimage ( TrueColorImage* img, dacpalette256 pal )
01074 {
01075   #ifndef minimal
01076    if ( truecolor2pal_table[0] == 255 ) {
01077       tfindfile ff ( "tc2pal.dat" );
01078       if ( !ff.getnextname().empty() ) {
01079          tnfilestream stream ( "tc2pal.dat", tnstream::reading );
01080          stream.readdata ( truecolor2pal_table, sizeof ( truecolor2pal_table ));
01081       } else {
01082          for ( int r = 0; r < 64; r++ )
01083             for ( int g = 0; g < 64; g++ )
01084                for ( int b = 0; b < 64; b++ ) {
01085                      int sml = r  + ( g << 6) + ( b << 12 );
01086       
01087                      int diff = 0xFFFFFFF;
01088                      int pix1 = 0;
01089             
01090                      for ( int k=0;k<256 ;k++ ) {
01091                         int actdif = sqr( pal[k][0]  - r ) + sqr( pal[k][1]  - g ) + sqr( pal[k][2]  - b );
01092 
01093                         if (actdif < diff) {
01094                            diff = actdif;
01095                            pix1 = k;
01096                         }
01097                      } 
01098                     truecolor2pal_table[sml] = pix1;
01099                }
01100        /*
01101          tnfilestream stream ( "tc2pal.dat", 2 );
01102          stream.writedata ( truecolor2pal_table, sizeof ( truecolor2pal_table ));
01103        */
01104       }
01105    }
01106   #endif
01107    int size = imagesize ( 1, 1, img->getxsize(), img->getysize() );
01108    char* newimg = new char[ size ] ;
01109    char* start = newimg;
01110    Uint16* wp = (Uint16*) newimg;
01111    wp[0] = img->getxsize()-1;
01112    wp[1] = img->getysize()-1;
01113 
01114    newimg+= 4;
01115 
01116    for ( int y = 0; y <= wp[1]; y++ )
01117       for ( int x = 0; x <= wp[0]; x++ ) {
01118          trgbpixel p  = img->getpix ( x, y );
01119 
01120 
01121          if ( p.channel.a <= alphabase*2/3 ) {
01122             int sml = ( p.channel.r >> 2) + (( p.channel.g >> 2) << 6) + (( p.channel.b >> 2) << 12);
01123 
01124             *newimg = truecolor2pal_table[sml];
01125 
01126          } else {
01127            *newimg = 255;
01128          }
01129          newimg++;
01130       }
01131 
01132    if ( newimg - start > size ) 
01133       printf("\a");
01134    return (char*)wp;
01135 }
01136 #endif
01137 
01138 fatalgraphicserror :: fatalgraphicserror ( const char* strng ) {
01139    strcpy ( st, strng );
01140 }
01141 
01142 fatalgraphicserror :: fatalgraphicserror ( void ) {
01143    st[0] = 0;
01144 }
01145                  
01146 void putmask ( int x1, int y1, void* vbuf, int newtransparence )
01147 {
01148       // int linecount = 0;
01149       // int rowcount = 0;
01150 
01151       Uint16* wp = (Uint16*) vbuf;
01152 
01153       char* basemembuf = (char*) (agmp->linearaddress + y1 * agmp->bytesperscanline + x1 * agmp->byteperpix );
01154       char* img = (char*) vbuf + 4;
01155 
01156       for ( int y = 0; y <= wp[1]; y++ ) {
01157          char* membuf = basemembuf + y * agmp->bytesperscanline;
01158 
01159          for ( int x = 0; x <= wp[0]; x++ ) {
01160             if ( *img != newtransparence )
01161                *membuf = *img;
01162             membuf += agmp->byteperpix;
01163             img++;
01164          }
01165       }
01166 }
01167 
01168 int graphicinitialized = 0;
01169 
01170 
01171 
01172 void* uncompress_rlepict ( void* pict )
01173 {
01174    trleheader* hd = (trleheader*) pict;
01175    if (hd->id == 16973) {
01176 
01177       int w, h;
01178       getpicsize( pict, w, h );
01179       w++;
01180       h++;
01181       void* newbuf = asc_malloc ( w * h + 4 );
01182       Uint16* wp = (Uint16*) newbuf;
01183       char* dest = (char*) newbuf;
01184       wp[0] = w-1;
01185       wp[1] = h-1;
01186       dest +=4;
01187    
01188       char* buf = (char*) pict;
01189       buf += sizeof ( *hd );
01190    
01191       for ( int c = 0; c < hd->size; c++ ) {
01192          if ( *buf == hd->rle ) {
01193             for ( int i = buf[1]; i > 0; i-- ) {
01194                *dest = buf[2];
01195                dest++;
01196             }
01197             buf += 3;
01198             c += 2;
01199    
01200          } else {
01201             *dest = *buf;
01202             dest++;
01203             
01204             buf++;
01205          }
01206       }
01207       return newbuf;
01208    } else
01209       return NULL;
01210 }
01211 
01212 
01213 
01214 void ellipse ( int x1, int y1, int x2, int y2, int color, float tolerance )
01215 {
01216    collategraphicoperations cgs ( x1, y1, x2, y2 );
01217 
01218    int midx = (x1 + x2) / 2;
01219    int midy = (y1 + y2) / 2;
01220    float xr = x2 - x1;
01221    float yr = y2 - y1;
01222 
01223    tolerance = tolerance / (xr+yr) *  80;
01224 
01225    xr= (xr/2)*(xr/2);
01226    yr= (yr/2)*(yr/2);
01227 
01228    for ( int y = y1; y <= y2; y++ )
01229       for ( int x = x1; x <= x2; x++ ) {
01230          float dx = x - midx;
01231          float dy = y - midy;
01232          float tmp = dx*dx/xr + dy*dy/yr;
01233 //         float tmp = dx*dx*yr + dy*dy*xr;
01234          if (  tmp <= 1 + tolerance && tmp >= 1 - tolerance )
01235             putpixel ( x, y, color );
01236       }
01237 
01238 }
01239 
01240 
01241 
01242 // char truecolor2pal_table[262144];
01243 
01244 
01245 dacpalette256* activepalette256;
01246 
01247 
01248 class tinitgfxengine {
01249         public:
01250           tinitgfxengine ( void );
01251        } initgfx;
01252 
01253 tinitgfxengine::tinitgfxengine ( void )
01254 {
01255 #ifdef use_truecolor2pal
01256    memset ( truecolor2pal_table, 255, sizeof ( truecolor2pal_table ));
01257 #endif
01258    hgmp = (tgraphmodeparameters *) & hardwaregraphmodeparameters;
01259    agmp = (tgraphmodeparameters *) & activegraphmodeparameters;
01260    activepalette256 = (dacpalette256*) &activepalette;
01261    xlatbuffer = asc_malloc ( xlatbuffersize );
01262 }
01263 
01264 
01265 void tvirtualdisplay :: init ( int x, int y, int color, int depth )
01266 {
01267    agmp = (tgraphmodeparameters *) & activegraphmodeparameters;
01268    oldparams = *agmp ;
01269    char* cbuf = (char*) asc_malloc ( x * y * depth/8 );
01270    if ( !cbuf )
01271       throw fatalgraphicserror ( "could not allocate memory !");
01272 
01273    buf = cbuf;
01274    for ( int i = 0; i < (x*y*depth/8); i++ )
01275       cbuf[i] = color;
01276 
01277    agmp->resolutionx   = x   ;
01278    agmp->resolutiony   = y   ;
01279    agmp->windowstatus  = 100 ;
01280    agmp->scanlinelength  = x*depth/8 ;
01281    agmp->scanlinenumber  = y ;
01282    agmp->bytesperscanline  = x * depth/8;
01283    agmp->byteperpix   = depth/8    ;
01284    agmp->linearaddress = (PointerSizedInt) buf ;
01285    agmp->bitperpix          = depth;
01286    agmp->directscreenaccess = 1;
01287    if ( depth ==24 || depth==32 ) {
01288       agmp->redmasksize = 8;
01289       agmp->greenmasksize = 8;
01290       agmp->bluemasksize = 8;
01291       agmp->redfieldposition = 0;
01292       agmp->greenfieldposition = 8;
01293       agmp->bluefieldposition = 16;
01294       surface = agmp->surface = new Surface (  Surface::CreateSurface( buf, x, y, depth, 0xff, 0xff00, 0xff0000) );
01295    } else {
01296       surface = agmp->surface = new Surface ( Surface::CreateSurface( buf, x, y, depth, agmp->scanlinelength ) );
01297       agmp->surface->assignDefaultPalette();
01298    }
01299 
01300 }
01301 
01302 Surface& tvirtualdisplay :: getSurface()
01303 {
01304    return *surface;
01305 }
01306 
01307 tvirtualdisplay :: tvirtualdisplay ( int x, int y )
01308 {
01309    init ( x, y, 0, 8  );
01310 }
01311 
01312 tvirtualdisplay :: tvirtualdisplay ( int x, int y, int color, int depth )
01313 {
01314    init ( x, y, color, depth );
01315 }
01316 
01317 
01318 tvirtualdisplay :: ~tvirtualdisplay ( )
01319 {
01320    delete agmp->surface;
01321    asc_free (  buf ) ;
01322    *agmp = oldparams;
01323 }
01324 
01325 
01326 collategraphicoperations :: collategraphicoperations ( void )
01327 {
01328    #ifndef _DOS_
01329    status = 1;
01330    x1 = -1; y1 = -1;
01331    x2 = -1; y2 = -1;
01332    olddirectscreenaccess = agmp->directscreenaccess;
01333    agmp->directscreenaccess = 1;
01334    #endif
01335 }
01336 
01337 collategraphicoperations :: collategraphicoperations ( int _x1, int _y1, int _x2, int _y2 )
01338 {
01339    #ifndef _DOS_
01340    status = 1;
01341    x1 = _x1; y1 = _y1;
01342    x2 = _x2; y2 = _y2;
01343    olddirectscreenaccess = agmp->directscreenaccess;
01344    agmp->directscreenaccess = 1;
01345    #endif
01346 }
01347 
01348 
01349 void collategraphicoperations :: on ( void )
01350 {
01351    #ifndef _DOS_
01352    agmp->directscreenaccess = 1;
01353    status = 1;
01354    #endif
01355 }
01356 
01357 void collategraphicoperations :: off ( void )
01358 {
01359    #ifndef _DOS_
01360    status = 0;
01361    agmp->directscreenaccess = 0;
01362    if (agmp->directscreenaccess == 0)
01363       copy2screen( x1, y1, x2, y2 );
01364 
01365    #endif
01366 }
01367 
01368 collategraphicoperations :: ~collategraphicoperations (  )
01369 {
01370    #ifndef _DOS_
01371    if ( status ) {
01372       agmp->directscreenaccess = olddirectscreenaccess;
01373       if (agmp->directscreenaccess == 0)
01374          copy2screen( x1, y1, x2, y2 );
01375    }
01376    #endif
01377 }
01378 
01379 void copySurface2screen( void )
01380 {
01381    if (agmp->directscreenaccess == 0)
01382       copy2screen( -1, -1, -1, -1 );
01383 }
01384 
01385 void copySurface2screen( int x1, int y1, int x2, int y2 )
01386 {
01387    if (agmp->directscreenaccess == 0)
01388       copy2screen( x1, y1, x2, y2 );
01389 }
01390 
01391 
01392 
01393 
01394 tgraphmodeparameters activegraphmodeparameters;
01395 tgraphmodeparameters hardwaregraphmodeparameters;
01396  
01397 int dpmscapabilities;
01398 int actdpmsmode;
01399  
01400 dacpalette256  activepalette;
01401 // int       palette16[256][4];
01402 void*     xlatbuffer;
01403  // dacpalette256  *activepalette256;
01404 
01405 
01406 
01407 
01408 
01409 
01410 void bar(int x1, int y1, int x2, int y2, char color)
01411 {
01412    collategraphicoperations cgo ( x1, y1, x2, y2 );
01413    if ( agmp->windowstatus == 100 ) {
01414       int spacelength = agmp->scanlinelength - (x2-x1) - 1;
01415       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01416       for ( int y = y1; y <= y2; y++ ) {
01417          for ( int x = x1; x <= x2; x++ ) 
01418             *(buf++) = color;
01419 
01420          buf+=spacelength;
01421       }
01422    }
01423 
01424 }
01425 
01426 
01427 void getimage(int x1, int y1, int x2, int y2, void *buffer)
01428 {
01429    if ( agmp->windowstatus == 100 ) {
01430       int spacelength = agmp->scanlinelength - (x2-x1) - 1;
01431       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01432 
01433       char* cb = (char*) buffer;
01434       Uint16* wb = (Uint16*) buffer;
01435    
01436       wb[0] = x2 - x1;
01437       wb[1] = y2 - y1;
01438       cb += 4;
01439 
01440       for ( int y = y1; y <= y2; y++ ) {
01441          for ( int x = x1; x <= x2; x++ )
01442             *(cb++) = *(buf++);
01443 
01444          buf+=spacelength;
01445       }
01446    }
01447 
01448 
01449 }
01450 
01451 void putimage ( int x1, int y1, void* img )
01452 {
01453    char* src = (char*) img;
01454 
01455    if ( agmp->windowstatus == 100 ) {
01456       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01457 
01458       trleheader*   hd = (trleheader*) img;
01459    
01460       if ( hd->id == 16973 ) { 
01461    
01462          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01463 
01464          int spacelength = agmp->scanlinelength - hd->x - 1;
01465 
01466          src  += sizeof ( *hd );
01467 
01468          int x = 0;
01469          for ( int c = 0; c < hd->size; c++ ) {
01470             if ( *src == hd->rle ) {
01471                x += src[1];
01472                for ( int i = src[1]; i > 0; i-- )
01473                   *(buf++) = src[2];
01474    
01475                src += 3;
01476                c+=2;
01477 
01478             } else {
01479                *(buf++) = *(src++);
01480                x++;
01481             }
01482 
01483             if ( x > hd->x ) {
01484                buf += spacelength;
01485                x = 0;
01486             }
01487          }
01488       } else {
01489          Uint16* w = (Uint16*) img;
01490          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01491          int spacelength = agmp->scanlinelength - *w - 1;
01492          src += 4;
01493          for ( int y = w[1] + 1; y > 0; y-- ) {
01494             for ( int x = w[0]+1; x > 0; x-- ) 
01495                *(buf++) = *(src++);
01496             
01497             buf+=spacelength;
01498          }
01499       }
01500    }
01501 
01502 }
01503 
01504 
01505 void putimage ( int x1, int y1, TrueColorImage* tci )
01506 {
01507   for ( int y = 0; y < tci->getysize(); y++ )
01508      for ( int x = 0; x < tci->getxsize(); x++ ) {
01509         trgbpixel t = tci->getpix ( x,y );
01510         putpixel ( x1 + x, y1 + y, t.channel.r + 256*t.channel.g + 256*256*t.channel.b );
01511      }
01512 }
01513 
01514 void putimage_noalpha ( int x1, int y1, TrueColorImage* tci )
01515 {
01516   for ( int y = 0; y < tci->getysize(); y++ )
01517      for ( int x = 0; x < tci->getxsize(); x++ ) {
01518         trgbpixel t = tci->getpix ( x,y );
01519         if (t.channel.a > alphabase * 2 / 3 )
01520            putpixel ( x1 + x, y1 + y, TCalpha );
01521         else
01522            putpixel ( x1 + x, y1 + y, t.channel.r + 256*t.channel.g + 256*256*t.channel.b );
01523      }
01524 }
01525 
01526 bool trgbpixel::isTransparent()
01527 {
01528    return ( channel.r == 0xfe && channel.g == 0xfe && channel.b == 0xfe ) ;
01529 }
01530 
01531 TrueColorImage* getimage ( int x1, int y1, int x2, int y2 )
01532 {
01533   TrueColorImage* tci = new TrueColorImage ( x2-x1+1, y2-y1+1 );
01534   for ( int y = 0; y < tci->getysize(); y++ )
01535      for ( int x = 0; x < tci->getxsize(); x++ ) {
01536         trgbpixel t;
01537         t.rgb = getpixel ( x1 + x, y1 + y );
01538         if ( t.isTransparent() )
01539            t.channel.a = alphabase;
01540         tci->setpix ( x, y, t );
01541      }
01542   return tci;
01543 }
01544 
01545 
01546 void putxlatfilter ( int x1, int y1, void* pic, char* xlattables )
01547 {
01548    char* src = (char*) pic;
01549 
01550    if ( agmp->windowstatus == 100 ) {
01551       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01552       trleheader*   hd = (trleheader*) pic;
01553 
01554       if ( hd->id == 16973 ) {
01555          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01556 
01557          int spacelength = agmp->scanlinelength - hd->x - 1;
01558          src  += sizeof ( *hd );
01559 
01560          int x = 0;
01561          for ( int c = 0; c < hd->size; c++ ) {
01562             if ( *src == hd->rle ) {
01563                x += src[1];
01564                for ( int i = src[1]; i > 0; i-- ) {
01565                   if ( src[2] != 255 )
01566                      *buf = xlattables[ src[2] * 256 + *buf ];
01567                   buf++;
01568                }
01569 
01570                src += 3;
01571                c+=2;
01572 
01573             } else {
01574                if ( *src != 255 )
01575                   *buf = xlattables[ *(src++) * 256 + *buf ];
01576                else
01577                   src++;
01578                buf++;
01579                x++;
01580             }
01581 
01582             if ( x > hd->x ) {
01583                buf += spacelength;
01584                x = 0;
01585             }
01586          }
01587       } else {
01588          Uint16* w = (Uint16*) pic;
01589          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01590          int spacelength = agmp->scanlinelength - *w - 1;
01591 
01592          src += 4;
01593          for ( int y = w[1] + 1; y > 0; y-- ) {
01594             for ( int x = w[0]+1; x > 0; x-- ) {
01595                if ( *src != 255 )
01596                   *buf = xlattables[ *(src++) * 256 + *buf ];
01597                else
01598                   src++;
01599                buf++;
01600             }
01601 
01602             buf+=spacelength;
01603          }
01604       }
01605    }
01606 
01607 }
01608 
01609 
01610 void putspriteimage ( int x1, int y1, void* pic )
01611 {
01612    char* src = (char*) pic;
01613 
01614    if ( agmp->windowstatus == 100 ) {
01615       trleheader*   hd = (trleheader*) pic;
01616       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01617       if ( hd->id == 16973 ) { 
01618          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01619          int spacelength = agmp->scanlinelength - hd->x - 1;
01620          src  += sizeof ( *hd );
01621 
01622          int x = 0;
01623          for ( int c = 0; c < hd->size; c++ ) {
01624             if ( *src == hd->rle ) {
01625                x += src[1];
01626                if ( src[2] != 255 ) {
01627                   for ( int i = src[1]; i > 0; i-- )
01628                      *(buf++) = src[2];
01629                } else
01630                   buf += src[1];
01631                src += 3;
01632                c+=2;
01633    
01634             } else {
01635                if ( *src != 255 )
01636                   *buf = *src;
01637                buf++;
01638                src++;
01639                x++;
01640             }
01641 
01642             if ( x > hd->x ) {
01643                buf += spacelength;
01644                x = 0;
01645             }
01646          }
01647       } else {
01648          Uint16* w = (Uint16*) pic;
01649          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01650          int spacelength = agmp->scanlinelength - *w - 1;
01651          src += 4;
01652          for ( int y = w[1] + 1; y > 0; y-- ) {
01653             for ( int x = w[0]+1; x > 0; x-- ) {
01654                char d = *(src++);
01655                if ( d != 255 )
01656                   *buf = d;
01657                buf++;
01658             }
01659             
01660             buf+=spacelength;
01661          }
01662       }
01663    }
01664 
01665 }
01666 
01667 void putrotspriteimage(int x1, int y1, void *pic, int rotationvalue)
01668 {
01669    char* src = (char*) pic;
01670 
01671    if ( agmp->windowstatus == 100 ) {
01672       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01673       trleheader*   hd = (trleheader*) pic;
01674    
01675       if ( hd->id == 16973 ) { 
01676          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01677 
01678          int spacelength = agmp->scanlinelength - hd->x - 1;
01679          src  += sizeof ( *hd );
01680 
01681          int x = 0;
01682          for ( int c = 0; c < hd->size; c++ ) {
01683             if ( *src == hd->rle ) {
01684                x += src[1];
01685                char d = src[2];
01686                if ( d != 255 ) {
01687                   if ( d >= 16 && d < 24 )
01688                      d += rotationvalue;
01689                   for ( int i = src[1]; i > 0; i-- )
01690                      *(buf++) = d;
01691                } else
01692                   buf += src[1];
01693    
01694                src += 3;
01695                c+=2;
01696    
01697             } else {
01698                char d = *(src++);
01699                if ( d != 255 ) {
01700                   if ( d >= 16 && d < 24 )
01701                      d += rotationvalue;
01702                   *(buf++) = d;
01703                } else
01704                  buf++;
01705 
01706                x++;
01707             }
01708 
01709             if ( x > hd->x ) {
01710                buf += spacelength;
01711                x = 0;
01712             }
01713          }
01714       } else {
01715          Uint16* w = (Uint16*) pic;
01716          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01717          int spacelength = agmp->scanlinelength - *w - 1;
01718          src += 4;
01719          for ( int y = w[1] + 1; y > 0; y-- ) {
01720             for ( int x = w[0]+1; x > 0; x-- ) {
01721                char d = *(src++);
01722                if ( d != 255 ) {
01723                   if ( d >= 16 && d < 24 )
01724                      d += rotationvalue;
01725    
01726                   *buf = d;
01727                }
01728                buf++;
01729             }
01730             
01731             buf+=spacelength;
01732          }
01733       }
01734    }
01735 
01736 }
01737 
01738 void putrotspriteimage90(int x1, int y1, void *pic, int rotationvalue)
01739 {
01740    Uint16* w = (Uint16*) pic;
01741    // char* c = (char*) pic + 4;
01742    int spacelength = agmp->scanlinelength - w[1] - 1;
01743    collategraphicoperations cgo ( x1, y1, x1+w[1], y1+w[0] );
01744 
01745    if ( agmp->windowstatus == 100 ) {
01746       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01747       for ( int y = 0; y <= w[0] ; y++ ) {
01748          for ( int x = 0; x <= w[1]; x++ ) {
01749             int d = getpixelfromimage ( pic, y, w[1] - x );
01750             if ( d != 255 && d != -1) {
01751                if ( d >= 16 && d < 24 )
01752                   d += rotationvalue;
01753 
01754                *buf = d;
01755             }
01756             buf++;
01757          }
01758          
01759          buf+=spacelength;
01760       }
01761    }
01762 
01763 }
01764 
01765 void putrotspriteimage180(int x1, int y1, void *pic, int rotationvalue)
01766 {
01767    Uint16* w = (Uint16*) pic;
01768    collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01769    // char* c = (char*) pic + 4;
01770    int spacelength = agmp->scanlinelength - *w - 1;
01771 
01772    if ( agmp->windowstatus == 100 ) {
01773       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01774       for ( int y = 0; y <= w[1] ; y++ ) {
01775          for ( int x = 0; x <= w[0]; x++ ) {
01776             int d = getpixelfromimage ( pic, w[0] - x, w[1] - y );
01777             if ( d != 255 && d != -1) {
01778                if ( d >= 16 && d < 24 )
01779                   d += rotationvalue;
01780 
01781                *buf = d;
01782             }
01783             buf++;
01784          }
01785          
01786          buf+=spacelength;
01787       }
01788    }
01789 
01790 }
01791 
01792 void putrotspriteimage270(int x1, int y1, void *pic, int rotationvalue)
01793 {
01794    Uint16* w = (Uint16*) pic;
01795    collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01796    // char* c = (char*) pic + 4;
01797    int spacelength = agmp->scanlinelength - *w - 1;
01798 
01799    if ( agmp->windowstatus == 100 ) {
01800       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01801       for ( int y = 0; y <= w[1] ; y++ ) {
01802          for ( int x = 0; x <= w[0]; x++ ) {
01803             int d = getpixelfromimage ( pic, w[1] - y, x );
01804             if ( d != 255 && d != -1) {
01805                if ( d >= 16 && d < 24 )
01806                   d += rotationvalue;
01807 
01808                *buf = d;
01809             }
01810             buf++;
01811          }
01812          
01813          buf+=spacelength;
01814       }
01815    }
01816 
01817 }
01818 
01819 void puttexture ( int x1, int y1, int x2, int y2, void *texture )
01820 {
01821    collategraphicoperations cgo ( x1, y1, x2, y2 );
01822    char* c = (char*) texture;
01823    int spacelength = agmp->scanlinelength - (x2 - x1) - 1;
01824 
01825    if ( agmp->windowstatus == 100 ) {
01826       int offset = agmp->scanlinelength * y1 + x1;
01827       char* buf = (char*) agmp->linearaddress;
01828       for ( int y = y1 ; y <= y2; y++ ) {
01829          for ( int x = x1; x <= x2 ; x++ ) {
01830             buf[offset] = c[offset];
01831             offset++;
01832          }
01833          
01834          offset+=spacelength;
01835       }
01836    }
01837 
01838 }
01839 
01840 
01841 void putspritetexture ( int x1, int y1, int x2, int y2, void *texture )
01842 {
01843    collategraphicoperations cgo ( x1, y1, x2, y2 );
01844    char* c = (char*) texture;
01845    int spacelength = agmp->scanlinelength - (x2 - x1) - 1;
01846 
01847    if ( agmp->windowstatus == 100 ) {
01848       int offset = agmp->scanlinelength * y1 + x1;
01849       char* buf = (char*) agmp->linearaddress;
01850       for ( int y = y1 ; y <= y2; y++ ) {
01851          for ( int x = x1; x <= x2 ; x++ ) {
01852             char d = c[offset];
01853             if ( d != 255 )
01854                buf[offset] = d;
01855             offset++;
01856          }
01857          
01858          offset+=spacelength;
01859       }
01860    }
01861 
01862 }
01863