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