00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00115 if (deltax >= deltay)
00116 {
00117
00118
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
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
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
00155 x = x1;
00156 y = y1;
00157
00158
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 }
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 }
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
00330
00331
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
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
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
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
00931
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
00978
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
01063 if ( tmp <= 1 + tolerance && tmp >= 1 - tolerance )
01064 putpixel ( x, y, color );
01065 }
01066
01067 }
01068
01069
01070
01071
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
01231 void* xlatbuffer;
01232
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
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
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
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
01712
01713
01714
01715
01716
01717
01718
01719
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
01777
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 }
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 }
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