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-2010  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 "misc.h"
00031 #include "newfont.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 
00852 
00853 TrueColorImage* smoothimage ( TrueColorImage* src )
00854 {
00855   TrueColorImage* dst = new TrueColorImage ( src->getxsize(), src->getysize() );
00856   for ( int y = 0; y < src->getysize(); y++ )
00857      for ( int x = 0; x < src->getxsize(); x++ ) {
00858         if ( src->getpix ( x, y ).channel.a < alphabase / 2 ) {
00859            int cnt = 0;
00860            int r = 0;
00861            int g = 0;
00862            int b = 0;
00863            for ( int a = -1; a <= 1; a++ )
00864               for ( int bb = -1; bb <= 1; bb++ ) {
00865                   int nx = x+a;
00866                   int ny = y+bb;
00867                   if ( nx >= 0 && ny >= 0 && nx < src->getxsize() && ny < src->getysize()) {
00868                      trgbpixel p = src->getpix( nx, ny );
00869                      if ( p.channel.a < alphabase/2 ) {
00870                         cnt++;
00871                         r += p.channel.r;
00872                         g += p.channel.g;
00873                         b += p.channel.b;
00874                      }
00875                   }
00876               }
00877 
00878            dst->setpix ( x, y, r/cnt, g/cnt, b/cnt, 0 );
00879         } else {
00880            dst->setpix ( x, y, 0, 0, 0, alphabase );
00881         }
00882      }
00883   return dst;
00884 }
00885 
00886 #define sqr(a) (a)*(a)
00887 #define cub(a) abs ((a)*(a)*(a))
00888 
00889 
00890 #ifndef minimal
00891  #include "basestrm.h"
00892 #endif
00893 
00894 
00895 int
00896 imagesize(int x1, int y1, int x2, int y2)
00897 {
00898         return ((x2 - x1 + 1) * (y2 - y1 + 1) + 4);
00899 }
00900 
00901 #if 0
00902 char* convertimage ( TrueColorImage* img, dacpalette256 pal )
00903 {
00904   #ifndef minimal
00905    if ( truecolor2pal_table[0] == 255 ) {
00906       tfindfile ff ( "tc2pal.dat" );
00907       if ( !ff.getnextname().empty() ) {
00908          tnfilestream stream ( "tc2pal.dat", tnstream::reading );
00909          stream.readdata ( truecolor2pal_table, sizeof ( truecolor2pal_table ));
00910       } else {
00911          for ( int r = 0; r < 64; r++ )
00912             for ( int g = 0; g < 64; g++ )
00913                for ( int b = 0; b < 64; b++ ) {
00914                      int sml = r  + ( g << 6) + ( b << 12 );
00915       
00916                      int diff = 0xFFFFFFF;
00917                      int pix1 = 0;
00918             
00919                      for ( int k=0;k<256 ;k++ ) {
00920                         int actdif = sqr( pal[k][0]  - r ) + sqr( pal[k][1]  - g ) + sqr( pal[k][2]  - b );
00921 
00922                         if (actdif < diff) {
00923                            diff = actdif;
00924                            pix1 = k;
00925                         }
00926                      } 
00927                     truecolor2pal_table[sml] = pix1;
00928                }
00929        /*
00930          tnfilestream stream ( "tc2pal.dat", 2 );
00931          stream.writedata ( truecolor2pal_table, sizeof ( truecolor2pal_table ));
00932        */
00933       }
00934    }
00935   #endif
00936    int size = imagesize ( 1, 1, img->getxsize(), img->getysize() );
00937    char* newimg = new char[ size ] ;
00938    char* start = newimg;
00939    Uint16* wp = (Uint16*) newimg;
00940    wp[0] = img->getxsize()-1;
00941    wp[1] = img->getysize()-1;
00942 
00943    newimg+= 4;
00944 
00945    for ( int y = 0; y <= wp[1]; y++ )
00946       for ( int x = 0; x <= wp[0]; x++ ) {
00947          trgbpixel p  = img->getpix ( x, y );
00948 
00949 
00950          if ( p.channel.a <= alphabase*2/3 ) {
00951             int sml = ( p.channel.r >> 2) + (( p.channel.g >> 2) << 6) + (( p.channel.b >> 2) << 12);
00952 
00953             *newimg = truecolor2pal_table[sml];
00954 
00955          } else {
00956            *newimg = 255;
00957          }
00958          newimg++;
00959       }
00960 
00961    if ( newimg - start > size ) 
00962       printf("\a");
00963    return (char*)wp;
00964 }
00965 #endif
00966 
00967 fatalgraphicserror :: fatalgraphicserror ( const char* strng ) {
00968    strcpy ( st, strng );
00969 }
00970 
00971 fatalgraphicserror :: fatalgraphicserror ( void ) {
00972    st[0] = 0;
00973 }
00974                  
00975 void putmask ( int x1, int y1, void* vbuf, int newtransparence )
00976 {
00977       // int linecount = 0;
00978       // int rowcount = 0;
00979 
00980       Uint16* wp = (Uint16*) vbuf;
00981 
00982       char* basemembuf = (char*) (agmp->linearaddress + y1 * agmp->bytesperscanline + x1 * agmp->byteperpix );
00983       char* img = (char*) vbuf + 4;
00984 
00985       for ( int y = 0; y <= wp[1]; y++ ) {
00986          char* membuf = basemembuf + y * agmp->bytesperscanline;
00987 
00988          for ( int x = 0; x <= wp[0]; x++ ) {
00989             if ( *img != newtransparence )
00990                *membuf = *img;
00991             membuf += agmp->byteperpix;
00992             img++;
00993          }
00994       }
00995 }
00996 
00997 int graphicinitialized = 0;
00998 
00999 
01000 
01001 void* uncompress_rlepict ( void* pict )
01002 {
01003    trleheader* hd = (trleheader*) pict;
01004    if (hd->id == 16973) {
01005 
01006       int w, h;
01007       getpicsize( pict, w, h );
01008       w++;
01009       h++;
01010       void* newbuf = malloc ( w * h + 4 );
01011       Uint16* wp = (Uint16*) newbuf;
01012       char* dest = (char*) newbuf;
01013       wp[0] = w-1;
01014       wp[1] = h-1;
01015       dest +=4;
01016    
01017       char* buf = (char*) pict;
01018       buf += sizeof ( *hd );
01019    
01020       for ( int c = 0; c < hd->size; c++ ) {
01021          if ( *buf == hd->rle ) {
01022             for ( int i = buf[1]; i > 0; i-- ) {
01023                *dest = buf[2];
01024                dest++;
01025             }
01026             buf += 3;
01027             c += 2;
01028    
01029          } else {
01030             *dest = *buf;
01031             dest++;
01032             
01033             buf++;
01034          }
01035       }
01036       return newbuf;
01037    } else
01038       return NULL;
01039 }
01040 
01041 
01042 
01043 void ellipse ( int x1, int y1, int x2, int y2, int color, float tolerance )
01044 {
01045    collategraphicoperations cgs ( x1, y1, x2, y2 );
01046 
01047    int midx = (x1 + x2) / 2;
01048    int midy = (y1 + y2) / 2;
01049    float xr = x2 - x1;
01050    float yr = y2 - y1;
01051 
01052    tolerance = tolerance / (xr+yr) *  80;
01053 
01054    xr= (xr/2)*(xr/2);
01055    yr= (yr/2)*(yr/2);
01056 
01057    for ( int y = y1; y <= y2; y++ )
01058       for ( int x = x1; x <= x2; x++ ) {
01059          float dx = x - midx;
01060          float dy = y - midy;
01061          float tmp = dx*dx/xr + dy*dy/yr;
01062 //         float tmp = dx*dx*yr + dy*dy*xr;
01063          if (  tmp <= 1 + tolerance && tmp >= 1 - tolerance )
01064             putpixel ( x, y, color );
01065       }
01066 
01067 }
01068 
01069 
01070 
01071 // char truecolor2pal_table[262144];
01072 
01073 
01074 dacpalette256* activepalette256;
01075 
01076 
01077 class tinitgfxengine {
01078         public:
01079           tinitgfxengine ( void );
01080        } initgfx;
01081 
01082 tinitgfxengine::tinitgfxengine ( void )
01083 {
01084 #ifdef use_truecolor2pal
01085    memset ( truecolor2pal_table, 255, sizeof ( truecolor2pal_table ));
01086 #endif
01087    hgmp = (tgraphmodeparameters *) & hardwaregraphmodeparameters;
01088    agmp = (tgraphmodeparameters *) & activegraphmodeparameters;
01089    activepalette256 = (dacpalette256*) &activepalette;
01090    xlatbuffer = malloc ( xlatbuffersize );
01091 }
01092 
01093 
01094 void tvirtualdisplay :: init ( int x, int y, int color, int depth )
01095 {
01096    agmp = (tgraphmodeparameters *) & activegraphmodeparameters;
01097    oldparams = *agmp ;
01098    char* cbuf = (char*) malloc ( x * y * depth/8 );
01099    if ( !cbuf )
01100       throw fatalgraphicserror ( "could not allocate memory !");
01101 
01102    buf = cbuf;
01103    for ( int i = 0; i < (x*y*depth/8); i++ )
01104       cbuf[i] = color;
01105 
01106    agmp->resolutionx   = x   ;
01107    agmp->resolutiony   = y   ;
01108    agmp->windowstatus  = 100 ;
01109    agmp->scanlinelength  = x*depth/8 ;
01110    agmp->scanlinenumber  = y ;
01111    agmp->bytesperscanline  = x * depth/8;
01112    agmp->byteperpix   = depth/8    ;
01113    agmp->linearaddress = (PointerSizedInt) buf ;
01114    agmp->bitperpix          = depth;
01115    agmp->directscreenaccess = 1;
01116    if ( depth ==24 || depth==32 ) {
01117       agmp->redmasksize = 8;
01118       agmp->greenmasksize = 8;
01119       agmp->bluemasksize = 8;
01120       agmp->redfieldposition = 0;
01121       agmp->greenfieldposition = 8;
01122       agmp->bluefieldposition = 16;
01123       surface = agmp->surface = new Surface (  Surface::CreateSurface( buf, x, y, depth, 0xff, 0xff00, 0xff0000) );
01124    } else {
01125       surface = agmp->surface = new Surface ( Surface::CreateSurface( buf, x, y, depth, agmp->scanlinelength ) );
01126       agmp->surface->assignDefaultPalette();
01127    }
01128 
01129 }
01130 
01131 Surface& tvirtualdisplay :: getSurface()
01132 {
01133    return *surface;
01134 }
01135 
01136 tvirtualdisplay :: tvirtualdisplay ( int x, int y )
01137 {
01138    init ( x, y, 0, 8  );
01139 }
01140 
01141 tvirtualdisplay :: tvirtualdisplay ( int x, int y, int color, int depth )
01142 {
01143    init ( x, y, color, depth );
01144 }
01145 
01146 
01147 tvirtualdisplay :: ~tvirtualdisplay ( )
01148 {
01149    delete agmp->surface;
01150    free (  buf ) ;
01151    *agmp = oldparams;
01152 }
01153 
01154 
01155 collategraphicoperations :: collategraphicoperations ( void )
01156 {
01157    #ifndef _DOS_
01158    status = 1;
01159    x1 = -1; y1 = -1;
01160    x2 = -1; y2 = -1;
01161    olddirectscreenaccess = agmp->directscreenaccess;
01162    agmp->directscreenaccess = 1;
01163    #endif
01164 }
01165 
01166 collategraphicoperations :: collategraphicoperations ( int _x1, int _y1, int _x2, int _y2 )
01167 {
01168    #ifndef _DOS_
01169    status = 1;
01170    x1 = _x1; y1 = _y1;
01171    x2 = _x2; y2 = _y2;
01172    olddirectscreenaccess = agmp->directscreenaccess;
01173    agmp->directscreenaccess = 1;
01174    #endif
01175 }
01176 
01177 
01178 void collategraphicoperations :: on ( void )
01179 {
01180    #ifndef _DOS_
01181    agmp->directscreenaccess = 1;
01182    status = 1;
01183    #endif
01184 }
01185 
01186 void collategraphicoperations :: off ( void )
01187 {
01188    #ifndef _DOS_
01189    status = 0;
01190    agmp->directscreenaccess = 0;
01191    if (agmp->directscreenaccess == 0)
01192       copy2screen( x1, y1, x2, y2 );
01193 
01194    #endif
01195 }
01196 
01197 collategraphicoperations :: ~collategraphicoperations (  )
01198 {
01199    #ifndef _DOS_
01200    if ( status ) {
01201       agmp->directscreenaccess = olddirectscreenaccess;
01202       if (agmp->directscreenaccess == 0)
01203          copy2screen( x1, y1, x2, y2 );
01204    }
01205    #endif
01206 }
01207 
01208 void copySurface2screen( void )
01209 {
01210    if (agmp->directscreenaccess == 0)
01211       copy2screen( -1, -1, -1, -1 );
01212 }
01213 
01214 void copySurface2screen( int x1, int y1, int x2, int y2 )
01215 {
01216    if (agmp->directscreenaccess == 0)
01217       copy2screen( x1, y1, x2, y2 );
01218 }
01219 
01220 
01221 
01222 
01223 tgraphmodeparameters activegraphmodeparameters;
01224 tgraphmodeparameters hardwaregraphmodeparameters;
01225  
01226 int dpmscapabilities;
01227 int actdpmsmode;
01228  
01229 dacpalette256  activepalette;
01230 // int       palette16[256][4];
01231 void*     xlatbuffer;
01232  // dacpalette256  *activepalette256;
01233 
01234 
01235 
01236 
01237 
01238 
01239 void bar(int x1, int y1, int x2, int y2, char color)
01240 {
01241    collategraphicoperations cgo ( x1, y1, x2, y2 );
01242    if ( agmp->windowstatus == 100 ) {
01243       int spacelength = agmp->scanlinelength - (x2-x1) - 1;
01244       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01245       for ( int y = y1; y <= y2; y++ ) {
01246          for ( int x = x1; x <= x2; x++ ) 
01247             *(buf++) = color;
01248 
01249          buf+=spacelength;
01250       }
01251    }
01252 
01253 }
01254 
01255 
01256 void getimage(int x1, int y1, int x2, int y2, void *buffer)
01257 {
01258    if ( agmp->windowstatus == 100 ) {
01259       int spacelength = agmp->scanlinelength - (x2-x1) - 1;
01260       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01261 
01262       char* cb = (char*) buffer;
01263       Uint16* wb = (Uint16*) buffer;
01264    
01265       wb[0] = x2 - x1;
01266       wb[1] = y2 - y1;
01267       cb += 4;
01268 
01269       for ( int y = y1; y <= y2; y++ ) {
01270          for ( int x = x1; x <= x2; x++ )
01271             *(cb++) = *(buf++);
01272 
01273          buf+=spacelength;
01274       }
01275    }
01276 
01277 
01278 }
01279 
01280 void putimage ( int x1, int y1, void* img )
01281 {
01282    char* src = (char*) img;
01283 
01284    if ( agmp->windowstatus == 100 ) {
01285       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01286 
01287       trleheader*   hd = (trleheader*) img;
01288    
01289       if ( hd->id == 16973 ) { 
01290    
01291          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01292 
01293          int spacelength = agmp->scanlinelength - hd->x - 1;
01294 
01295          src  += sizeof ( *hd );
01296 
01297          int x = 0;
01298          for ( int c = 0; c < hd->size; c++ ) {
01299             if ( *src == hd->rle ) {
01300                x += src[1];
01301                for ( int i = src[1]; i > 0; i-- )
01302                   *(buf++) = src[2];
01303    
01304                src += 3;
01305                c+=2;
01306 
01307             } else {
01308                *(buf++) = *(src++);
01309                x++;
01310             }
01311 
01312             if ( x > hd->x ) {
01313                buf += spacelength;
01314                x = 0;
01315             }
01316          }
01317       } else {
01318          Uint16* w = (Uint16*) img;
01319          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01320          int spacelength = agmp->scanlinelength - *w - 1;
01321          src += 4;
01322          for ( int y = w[1] + 1; y > 0; y-- ) {
01323             for ( int x = w[0]+1; x > 0; x-- ) 
01324                *(buf++) = *(src++);
01325             
01326             buf+=spacelength;
01327          }
01328       }
01329    }
01330 
01331 }
01332 
01333 
01334 void putimage ( int x1, int y1, TrueColorImage* tci )
01335 {
01336   for ( int y = 0; y < tci->getysize(); y++ )
01337      for ( int x = 0; x < tci->getxsize(); x++ ) {
01338         trgbpixel t = tci->getpix ( x,y );
01339         putpixel ( x1 + x, y1 + y, t.channel.r + 256*t.channel.g + 256*256*t.channel.b );
01340      }
01341 }
01342 
01343 void putimage_noalpha ( int x1, int y1, TrueColorImage* tci )
01344 {
01345   for ( int y = 0; y < tci->getysize(); y++ )
01346      for ( int x = 0; x < tci->getxsize(); x++ ) {
01347         trgbpixel t = tci->getpix ( x,y );
01348         if (t.channel.a > alphabase * 2 / 3 )
01349            putpixel ( x1 + x, y1 + y, TCalpha );
01350         else
01351            putpixel ( x1 + x, y1 + y, t.channel.r + 256*t.channel.g + 256*256*t.channel.b );
01352      }
01353 }
01354 
01355 bool trgbpixel::isTransparent()
01356 {
01357    return ( channel.r == 0xfe && channel.g == 0xfe && channel.b == 0xfe ) ;
01358 }
01359 
01360 TrueColorImage* getimage ( int x1, int y1, int x2, int y2 )
01361 {
01362   TrueColorImage* tci = new TrueColorImage ( x2-x1+1, y2-y1+1 );
01363   for ( int y = 0; y < tci->getysize(); y++ )
01364      for ( int x = 0; x < tci->getxsize(); x++ ) {
01365         trgbpixel t;
01366         t.rgb = getpixel ( x1 + x, y1 + y );
01367         if ( t.isTransparent() )
01368            t.channel.a = alphabase;
01369         tci->setpix ( x, y, t );
01370      }
01371   return tci;
01372 }
01373 
01374 
01375 void putxlatfilter ( int x1, int y1, void* pic, char* xlattables )
01376 {
01377    char* src = (char*) pic;
01378 
01379    if ( agmp->windowstatus == 100 ) {
01380       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01381       trleheader*   hd = (trleheader*) pic;
01382 
01383       if ( hd->id == 16973 ) {
01384          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01385 
01386          int spacelength = agmp->scanlinelength - hd->x - 1;
01387          src  += sizeof ( *hd );
01388 
01389          int x = 0;
01390          for ( int c = 0; c < hd->size; c++ ) {
01391             if ( *src == hd->rle ) {
01392                x += src[1];
01393                for ( int i = src[1]; i > 0; i-- ) {
01394                   if ( src[2] != 255 )
01395                      *buf = xlattables[ src[2] * 256 + *buf ];
01396                   buf++;
01397                }
01398 
01399                src += 3;
01400                c+=2;
01401 
01402             } else {
01403                if ( *src != 255 )
01404                   *buf = xlattables[ *(src++) * 256 + *buf ];
01405                else
01406                   src++;
01407                buf++;
01408                x++;
01409             }
01410 
01411             if ( x > hd->x ) {
01412                buf += spacelength;
01413                x = 0;
01414             }
01415          }
01416       } else {
01417          Uint16* w = (Uint16*) pic;
01418          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01419          int spacelength = agmp->scanlinelength - *w - 1;
01420 
01421          src += 4;
01422          for ( int y = w[1] + 1; y > 0; y-- ) {
01423             for ( int x = w[0]+1; x > 0; x-- ) {
01424                if ( *src != 255 )
01425                   *buf = xlattables[ *(src++) * 256 + *buf ];
01426                else
01427                   src++;
01428                buf++;
01429             }
01430 
01431             buf+=spacelength;
01432          }
01433       }
01434    }
01435 
01436 }
01437 
01438 
01439 void putspriteimage ( int x1, int y1, void* pic )
01440 {
01441    char* src = (char*) pic;
01442 
01443    if ( agmp->windowstatus == 100 ) {
01444       trleheader*   hd = (trleheader*) pic;
01445       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01446       if ( hd->id == 16973 ) { 
01447          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01448          int spacelength = agmp->scanlinelength - hd->x - 1;
01449          src  += sizeof ( *hd );
01450 
01451          int x = 0;
01452          for ( int c = 0; c < hd->size; c++ ) {
01453             if ( *src == hd->rle ) {
01454                x += src[1];
01455                if ( src[2] != 255 ) {
01456                   for ( int i = src[1]; i > 0; i-- )
01457                      *(buf++) = src[2];
01458                } else
01459                   buf += src[1];
01460                src += 3;
01461                c+=2;
01462    
01463             } else {
01464                if ( *src != 255 )
01465                   *buf = *src;
01466                buf++;
01467                src++;
01468                x++;
01469             }
01470 
01471             if ( x > hd->x ) {
01472                buf += spacelength;
01473                x = 0;
01474             }
01475          }
01476       } else {
01477          Uint16* w = (Uint16*) pic;
01478          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01479          int spacelength = agmp->scanlinelength - *w - 1;
01480          src += 4;
01481          for ( int y = w[1] + 1; y > 0; y-- ) {
01482             for ( int x = w[0]+1; x > 0; x-- ) {
01483                char d = *(src++);
01484                if ( d != 255 )
01485                   *buf = d;
01486                buf++;
01487             }
01488             
01489             buf+=spacelength;
01490          }
01491       }
01492    }
01493 
01494 }
01495 
01496 void putrotspriteimage(int x1, int y1, void *pic, int rotationvalue)
01497 {
01498    char* src = (char*) pic;
01499 
01500    if ( agmp->windowstatus == 100 ) {
01501       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01502       trleheader*   hd = (trleheader*) pic;
01503    
01504       if ( hd->id == 16973 ) { 
01505          collategraphicoperations cgo ( x1, y1, x1+hd->x, y1+hd->y );
01506 
01507          int spacelength = agmp->scanlinelength - hd->x - 1;
01508          src  += sizeof ( *hd );
01509 
01510          int x = 0;
01511          for ( int c = 0; c < hd->size; c++ ) {
01512             if ( *src == hd->rle ) {
01513                x += src[1];
01514                char d = src[2];
01515                if ( d != 255 ) {
01516                   if ( d >= 16 && d < 24 )
01517                      d += rotationvalue;
01518                   for ( int i = src[1]; i > 0; i-- )
01519                      *(buf++) = d;
01520                } else
01521                   buf += src[1];
01522    
01523                src += 3;
01524                c+=2;
01525    
01526             } else {
01527                char d = *(src++);
01528                if ( d != 255 ) {
01529                   if ( d >= 16 && d < 24 )
01530                      d += rotationvalue;
01531                   *(buf++) = d;
01532                } else
01533                  buf++;
01534 
01535                x++;
01536             }
01537 
01538             if ( x > hd->x ) {
01539                buf += spacelength;
01540                x = 0;
01541             }
01542          }
01543       } else {
01544          Uint16* w = (Uint16*) pic;
01545          collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01546          int spacelength = agmp->scanlinelength - *w - 1;
01547          src += 4;
01548          for ( int y = w[1] + 1; y > 0; y-- ) {
01549             for ( int x = w[0]+1; x > 0; x-- ) {
01550                char d = *(src++);
01551                if ( d != 255 ) {
01552                   if ( d >= 16 && d < 24 )
01553                      d += rotationvalue;
01554    
01555                   *buf = d;
01556                }
01557                buf++;
01558             }
01559             
01560             buf+=spacelength;
01561          }
01562       }
01563    }
01564 
01565 }
01566 
01567 void putrotspriteimage90(int x1, int y1, void *pic, int rotationvalue)
01568 {
01569    Uint16* w = (Uint16*) pic;
01570    // char* c = (char*) pic + 4;
01571    int spacelength = agmp->scanlinelength - w[1] - 1;
01572    collategraphicoperations cgo ( x1, y1, x1+w[1], y1+w[0] );
01573 
01574    if ( agmp->windowstatus == 100 ) {
01575       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01576       for ( int y = 0; y <= w[0] ; y++ ) {
01577          for ( int x = 0; x <= w[1]; x++ ) {
01578             int d = getpixelfromimage ( pic, y, w[1] - x );
01579             if ( d != 255 && d != -1) {
01580                if ( d >= 16 && d < 24 )
01581                   d += rotationvalue;
01582 
01583                *buf = d;
01584             }
01585             buf++;
01586          }
01587          
01588          buf+=spacelength;
01589       }
01590    }
01591 
01592 }
01593 
01594 void putrotspriteimage180(int x1, int y1, void *pic, int rotationvalue)
01595 {
01596    Uint16* w = (Uint16*) pic;
01597    collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01598    // char* c = (char*) pic + 4;
01599    int spacelength = agmp->scanlinelength - *w - 1;
01600 
01601    if ( agmp->windowstatus == 100 ) {
01602       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01603       for ( int y = 0; y <= w[1] ; y++ ) {
01604          for ( int x = 0; x <= w[0]; x++ ) {
01605             int d = getpixelfromimage ( pic, w[0] - x, w[1] - y );
01606             if ( d != 255 && d != -1) {
01607                if ( d >= 16 && d < 24 )
01608                   d += rotationvalue;
01609 
01610                *buf = d;
01611             }
01612             buf++;
01613          }
01614          
01615          buf+=spacelength;
01616       }
01617    }
01618 
01619 }
01620 
01621 void putrotspriteimage270(int x1, int y1, void *pic, int rotationvalue)
01622 {
01623    Uint16* w = (Uint16*) pic;
01624    collategraphicoperations cgo ( x1, y1, x1+w[0], y1+w[1] );
01625    // char* c = (char*) pic + 4;
01626    int spacelength = agmp->scanlinelength - *w - 1;
01627 
01628    if ( agmp->windowstatus == 100 ) {
01629       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01630       for ( int y = 0; y <= w[1] ; y++ ) {
01631          for ( int x = 0; x <= w[0]; x++ ) {
01632             int d = getpixelfromimage ( pic, w[1] - y, x );
01633             if ( d != 255 && d != -1) {
01634                if ( d >= 16 && d < 24 )
01635                   d += rotationvalue;
01636 
01637                *buf = d;
01638             }
01639             buf++;
01640          }
01641          
01642          buf+=spacelength;
01643       }
01644    }
01645 
01646 }
01647 
01648 void puttexture ( int x1, int y1, int x2, int y2, void *texture )
01649 {
01650    collategraphicoperations cgo ( x1, y1, x2, y2 );
01651    char* c = (char*) texture;
01652    int spacelength = agmp->scanlinelength - (x2 - x1) - 1;
01653 
01654    if ( agmp->windowstatus == 100 ) {
01655       int offset = agmp->scanlinelength * y1 + x1;
01656       char* buf = (char*) agmp->linearaddress;
01657       for ( int y = y1 ; y <= y2; y++ ) {
01658          for ( int x = x1; x <= x2 ; x++ ) {
01659             buf[offset] = c[offset];
01660             offset++;
01661          }
01662          
01663          offset+=spacelength;
01664       }
01665    }
01666 
01667 }
01668 
01669 
01670 void putspritetexture ( int x1, int y1, int x2, int y2, void *texture )
01671 {
01672    collategraphicoperations cgo ( x1, y1, x2, y2 );
01673    char* c = (char*) texture;
01674    int spacelength = agmp->scanlinelength - (x2 - x1) - 1;
01675 
01676    if ( agmp->windowstatus == 100 ) {
01677       int offset = agmp->scanlinelength * y1 + x1;
01678       char* buf = (char*) agmp->linearaddress;
01679       for ( int y = y1 ; y <= y2; y++ ) {
01680          for ( int x = x1; x <= x2 ; x++ ) {
01681             char d = c[offset];
01682             if ( d != 255 )
01683                buf[offset] = d;
01684             offset++;
01685          }
01686          
01687          offset+=spacelength;
01688       }
01689    }
01690 
01691 }
01692 
01693 void putimageprt ( int x1, int y1, int x2, int y2, void *texture, int dx, int dy )
01694 {
01695    collategraphicoperations cgo ( x1, y1, x2, y2 );
01696    int spacelength = agmp->scanlinelength - (x2-x1) - 1;
01697 
01698    if ( agmp->windowstatus == 100 ) {
01699       char* buf = (char*) (agmp->scanlinelength * y1 + x1 * agmp->byteperpix + agmp->linearaddress);
01700       for ( int y = y1; y <= y2 ; y++ ) {
01701          for ( int x = x1; x <= x2; x++ ) {
01702             int p = getpixelfromimage ( texture, x - x1 + dx, y - y1 + dy );
01703             if ( p != -1 ) 
01704                *buf = p;
01705 
01706             buf++;
01707          }
01708          buf+=spacelength;
01709       }
01710       /*
01711       for ( int y = 0; y <= w[1] ; y++ ) {
01712          for ( int x = 0; x <= w[0]; x++ ) {
01713             int p = getpixelfromimage ( texture, x + dx, y + dy );
01714             if ( p != -1 )
01715                *buf = p;
01716 
01717             buf++;
01718          }
01719          buf+=spacelength;
01720       } */
01721    }
01722 
01723 }
01724 
01725 void copybuf2displaymemory(int size, void *buf)
01726 {
01727    collategraphicoperations cgo ;
01728    memcpy ( (void*) agmp->linearaddress, buf, size );
01729 }
01730 
01731 #if 0
01732 void* xlatpict ( ppixelxlattable xl, void* vbuf )
01733 {
01734 
01735    char* buf = (char*) vbuf;
01736 
01737    Uint16* wp = (Uint16*) xlatbuffer;
01738    char* dest = (char*) xlatbuffer;
01739 
01740    trleheader*   hd = (trleheader*) vbuf; 
01741 
01742    if ( hd->id == 16973 ) {
01743       memcpy ( xlatbuffer, vbuf, sizeof ( *hd ));
01744 
01745       trleheader* desthead = (trleheader*) xlatbuffer; 
01746 
01747 
01748       dest += sizeof ( *hd );
01749       buf  += sizeof ( *hd );
01750 
01751       for ( int c = 0; c < hd->size; c++ ) 
01752          if ( *buf == hd->rle ) {
01753             *(dest++) = *(buf++);
01754             *(dest++) = *(buf++);
01755             *(dest++) = (*xl)[ *(buf++) ];
01756 
01757             c += 2;
01758 
01759          } else {
01760             int newpix = (*xl)[ *(buf++) ];
01761             if ( newpix == hd->rle ) {
01762                *(dest++) = hd->rle;
01763                *(dest++) = 1;
01764                *(dest++) = hd->rle;
01765                desthead->size += 2;
01766             } else
01767                *(dest++) = newpix;
01768          }
01769       
01770    } else {
01771       Uint16* wp2 = (Uint16*) vbuf;
01772 
01773       wp[0] = wp2[0];
01774       wp[1] = wp2[1];
01775 /*
01776       if ( ( wp[0] + 1 ) * ( wp[1] + 1 ) + 4 >= xlatbuffersize )
01777          throw fatalgraphicserror ( "halfpict : picture larger than buffer ! " );
01778 */
01779       dest += 4;
01780       buf += 4;
01781 
01782       for ( int c = (wp2[0] + 1) * (wp2[1] + 1); c > 0; c-- ) {
01783          *dest = (*xl)[ *buf ];
01784          dest++;
01785          buf++;
01786       }
01787 
01788    }
01789    return xlatbuffer;
01790 }
01791 #endif
01792 
01793 int loga2 ( int a )
01794 {
01795    int l = 0;
01796    if ( a ) 
01797       while ( ! (a & 1)) {
01798          a >>= 1;
01799          l++;
01800       }
01801    return l;
01802 }
01803 
01804 
01805 
01806 void showtext ( const char* text, int x, int y, int textcol )
01807 {
01808    if ( !activefontsettings.font )
01809      return;
01810 
01811    if ( !text )
01812      return;
01813  
01814    char* fb = (char*)(x * agmp->byteperpix + y * agmp->scanlinelength + agmp->linearaddress);
01815    int fontheight;
01816    int extraheight = 0;
01817    if ( activefontsettings.height == 0 )
01818       fontheight = activefontsettings.font->height;
01819    else
01820       if ( activefontsettings.height > activefontsettings.font->height ) {
01821          fontheight = activefontsettings.font->height;
01822          extraheight = activefontsettings.height - activefontsettings.font->height;
01823       } else 
01824          fontheight = activefontsettings.height;
01825 
01826     const char* t = text;
01827     int length = 0;
01828 
01829     char* characterpointer[1024];
01830     int    characterwidth[1024];
01831     int    characterdist[1024];
01832     int ps = 0;
01833     while ( *t ) {
01834        if ( activefontsettings.font->character[int(*t)].width ) {
01835           characterwidth[ps] = activefontsettings.font->character[int(*t)].width;
01836           characterpointer[ps] = activefontsettings.font->character[int(*t)].memposition + 2;
01837           if ( t[1] )
01838              characterdist[ps] = activefontsettings.font->kerning[int(t[1])][int(t[0])] + 2;
01839           else
01840              characterdist[ps] = 0;
01841           length +=activefontsettings.font->character[int(*t)].width;
01842           length += characterdist[ps];
01843           ps++;
01844        }
01845        t++;
01846     }
01847     int leftextralength = 0;
01848     int rightextralength = 0;
01849 
01850     if ( !activefontsettings.length )
01851        leftextralength = rightextralength = 0;
01852     else {
01853        if ( activefontsettings.justify == 0 ) {
01854           leftextralength = 0;
01855           if ( activefontsettings.length > length )
01856              rightextralength = activefontsettings.length - length;
01857           else {
01858              rightextralength = 0;
01859              length = activefontsettings.length;
01860           }
01861        } else
01862        if ( activefontsettings.justify == 1 ) {
01863           if ( activefontsettings.length > length ) {
01864              leftextralength = (activefontsettings.length - length+2)/2;
01865              rightextralength = activefontsettings.length - length - leftextralength;
01866           } else {
01867              rightextralength = 0;
01868              leftextralength = 0;
01869              length = activefontsettings.length;
01870           }
01871        } else
01872        if ( activefontsettings.justify == 2 ) {
01873           rightextralength = 0;
01874           if ( activefontsettings.length > length )
01875              leftextralength = activefontsettings.length - length;
01876           else {
01877              leftextralength = 0;
01878              length = activefontsettings.length;
01879           }
01880        } 
01881        
01882     }
01883     collategraphicoperations cgo ( x, y, x +length + leftextralength + rightextralength, y + fontheight + extraheight );
01884 
01885     int suppressbkgr = 0;
01886     int spacelength = agmp->scanlinelength - (length + leftextralength + rightextralength);
01887     if ( activefontsettings.background == 255 ) {
01888        spacelength += leftextralength + rightextralength;
01889        fb += leftextralength;
01890        leftextralength = rightextralength = 0;
01891        extraheight = 0;
01892     }
01893     for ( int yl = 0; yl < fontheight; yl++ ) {
01894        if ( leftextralength ) 
01895           for ( int i = 0; i < leftextralength; i++ )
01896              *(fb++) = activefontsettings.background;
01897 
01898        int x = 0;
01899        ps = 0;
01900        while ( x < length ) {
01901           int cx;
01902           for ( cx = characterwidth[ps]; cx > 0 && x < length; cx--) {
01903              int pix = *(characterpointer[ps]++);
01904              if ( pix ) {
01905                 if ( textcol != -1 )
01906                    *fb = textcol;
01907                 else
01908                    *fb = pix;
01909              } else
01910                 if ( activefontsettings.background != 255 ) {
01911                    if ( suppressbkgr )
01912                       suppressbkgr--;
01913                    else
01914                      *fb = activefontsettings.background;
01915                 }
01916              fb++;
01917              x++;
01918           } /* endfor */
01919           if ( x < length ) {
01920              if ( characterdist[ps] > 0 ) {
01921                 for (int i = characterdist[ps]; i && x < length; i-- ) {
01922                    if ( activefontsettings.background != 255 )
01923                      *fb = activefontsettings.background;
01924                    fb++;
01925                    x++;
01926                 } /* endfor */
01927              } else {
01928                 fb += characterdist[ps];
01929                 x += characterdist[ps];
01930                 suppressbkgr = -characterdist[ps];
01931              }
01932           } else {
01933              characterpointer[ps] += cx;
01934           }
01935           ps++;
01936        }
01937 
01938        if ( rightextralength )
01939           for ( int i = 0; i < rightextralength; i++ )
01940              *(fb++) = activefontsettings.background;
01941 
01942        fb += spacelength;
01943     }
01944     if ( extraheight )
01945        for ( int yl = extraheight; yl > 0; yl-- ) {
01946           for ( int x = length + leftextralength + rightextralength; x > 0; x-- )
01947              *(fb++) = activefontsettings.background;
01948           fb += spacelength;
01949        }
01950 
01951 }
01952 
01953 void showtext2 ( const ASCString& text, int x, int y )
01954 {
01955    showtext ( text.c_str(), x, y, activefontsettings.color );
01956 }
01957 
01958 void showtext2c ( const ASCString& text, int x, int y )
01959 {           
01960    showtext ( text.c_str(), x, y, -1 );
01961 }
01962 
01963 #ifdef use_truecolor2pal
01964 void* convertSurface ( SDLmm::Surface& s, bool paletteTranslation )
01965 {
01966   s.Lock();
01967 
01968   char* buf = new char[ imagesize ( 1, 1, s.w(), s.h())];
01969   Uint16* wp = (Uint16*) buf;
01970   wp[0] = s.w()-1;
01971   wp[1] = s.h()-1;
01972   SDLmm::PixelFormat fmt = s.GetPixelFormat();
01973   if ( fmt.BytesPerPixel() == 1 && !paletteTranslation ) {
01974      for ( int y = 0; y < s.h(); y++ )
01975         for ( int x = 0; x < s.w(); x++ )
01976            buf[4 + s.w()*y+x] = s.GetPixel ( x, y );
01977 
01978   } else {
01979 
01980      for ( int y = 0; y < s.h(); y++ )
01981         for ( int x = 0; x < s.w(); x++ ) {
01982            Uint8 red, green, blue, alpha;
01983            fmt.GetRGBA ( s.GetPixel ( x, y ), red, green, blue, alpha);
01984 
01985            if ( alpha < 128 )
01986               buf[4 + s.w()*y+x] = 255;
01987            else
01988               buf[4 + s.w()*y+x] = truecolor2pal_table[ (red >> 2) +
01989                                                         (( green >> 2) << 6) +
01990                                                         (( blue >> 2) << 12) ];
01991         }
01992   }
01993 
01994   s.Unlock();
01995   return buf;
01996 }
01997 #endif
01998 
01999 SPoint getPixelRotationLocation( SPoint pos, int width, int height, int degrees )
02000 {
02001    const float pi = 3.14159265;
02002    double angle = double(-degrees) / 360 * 2 * pi;
02003 
02004    double dx = pos.x - width/2 ;
02005    double dy = height/2 - pos.y;
02006    float nx, ny;
02007    if ( degrees == 0 ) {
02008       nx = dx;
02009       ny = dy;
02010    } else
02011       if ( degrees == 180 || degrees == -180) {
02012          nx = -dx;
02013          ny = -dy;
02014       } else {
02015          float wnk ;
02016          if ( dy  )
02017             wnk = atan2 ( -dx, dy );
02018          else
02019             if ( dx < 0 )
02020                wnk = pi/2;
02021             else
02022                wnk = -pi/2;
02023 
02024          wnk += angle;
02025          float radius = sqrt ( dx * dx + dy * dy );
02026 
02027          nx = -radius * sin ( wnk );
02028          ny = radius * cos ( wnk );
02029       }
02030 
02031    return SPoint( int( width/2 + nx), int ( -ny + height/2));
02032 }
02033 
02034 

Generated on Mon May 21 01:26:28 2012 for Advanced Strategic Command by  doxygen 1.5.1