File: basegfx.h

package info (click to toggle)
asc 2.6.1.0-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 81,740 kB
  • sloc: cpp: 158,704; sh: 11,544; ansic: 6,736; makefile: 604; perl: 138
file content (438 lines) | stat: -rw-r--r-- 20,470 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
/*! \file basegfx.h
   \brief basegfx.h is the interface for the legacy graphic routines (of which some are platform dependent).

   basegfx.h additionally includes the definitions of routines, 
    whose implementation is platform dependant, but whose interface
    is the same on all platforms. Their implementation is in the various
    subdirectories for the platforms.
    The graphic routines are older than ASC itself, first written in 1993 as a protected
    mode replacement for Borlands BGI. (That's why the uncompressed image structure
    is exactly the same as in the BGI).

   the code here is being replaced by the new graphics system found in the graphics subdirectory
*/

/*
    This file is part of Advanced Strategic Command; http://www.asc-hq.de
    Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; see the file COPYING. If not, write to the 
    Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
    Boston, MA  02111-1307  USA
*/

#ifndef basegfxH
#define basegfxH

#include "libs/sdlmm/src/sdlmm.h"
#include "global.h"
#include "palette.h"
#include "sdl/graphics.h"
#include "graphics/surface.h"

#pragma pack(1)

const int colorDepth = 4;



//! a graphical surface.
struct  tgraphmodeparameters {
            int           resolutionx      ;       //!< the number of visible pixels in x direction
            int           resolutiony      ;       //!< the number of visible pixels in y direction
            int           actsetpage       ;       //!< only used in DOS where it may be necessary to access the graphic memory in 64 kB pages
            int           windowstatus     ;       //!< determines whether the memory is a linear (windowstatus==100) or paged. When using SDL, the memory is always linear addressable.
            int           granularity      ;       //!< the offset in graphics memory between two pages. Can be ignored nowadays
            int           scanlinelength   ;       //!< the size of a line in byte (may be larger than resolutionx due to offscreen memory)
            int           scanlinenumber   ;       //!< the number of lines (may be larger than resolutiony due to offscreen memory)
            int           bytesperscanline ;       //!< the size of a line in byte
            int           activegraphmode  ;       //!< the number of the active graphic mode. Can be ignored nowadays
            int           videomemory      ;       //!< the amount of memory in the video card. Not used any more.
            int           byteperpix       ;       //!< the distance between two pixel
            PointerSizedInt linearaddress    ;       //!< the pointer to the actual memory (typecast to char* )
            int           pagetoset        ;       //!< only used in DOS with paged graphic memory
            Uint8          redmasksize       ;      //!< RGB only: the number of bits in the red component
            Uint8          redfieldposition  ;      //!< RGB only: the position of the first red bit relative to the start of the pixel
            Uint8          greenmasksize     ;      //!< RGB only: the number of bits in the green component
            Uint8          greenfieldposition;      //!< RGB only: the position of the first green bit relative to the start of the pixel
            Uint8          bluemasksize      ;      //!< RGB only: the number of bits in the blue component
            Uint8          bluefieldposition ;      //!< RGB only: the position of the first blue bit relative to the start of the pixel
            Uint8          bitperpix         ;      //!< the size of a pixel(?) in bits
            Uint8          memorymodel;             //!< unused
            int           directscreenaccess;      //!< if 0 no call to an update function (which copies the buffer to the screen) is performed
            Surface*      surface;
            tgraphmodeparameters() : surface(NULL) {};
    };


struct trleheader {
   Uint16 id;
   Uint16 size;
   Uint8 rle;
   Uint16 x;
   Uint16 y;
};

const int black = 0;
const int    blue        = 1;
const int    green       = 2;
const int    cyan        = 3;
const int    red         = 4;
const int    magenta     = 5 ;
const int    brown       = 6  ;
const int    lightgray   = 7   ;
const int    darkgray    = 8    ;
const int    lightblue   = 9     ;
const int    lightgreen  = 42  ; // 10      
const int    lightcyan   = 119 ; // 11      
const int    lightred    = 52  ; // 12        
const int    lightmagenta = 5  ; // 13         
const int    yellow       = 103;  // 14          
const int    white        = 160;  // 15           

extern tgraphmodeparameters   *agmp;
extern tgraphmodeparameters   *hgmp;

extern dacpalette256* activepalette256;


extern tgraphmodeparameters activegraphmodeparameters;
extern tgraphmodeparameters hardwaregraphmodeparameters;

extern dacpalette256 activepalette;
// extern int       palette16[256][4];
extern void*     xlatbuffer;



 //! paints a colored bar
 extern void bar(int x1, int y1, int x2, int y2, Uint8 color);

 //! copy an image to a buffer. buffer must have been alloced before with malloc ( imagesize ( x1,y1,x2,y2 ))
 extern void getimage(int x1, int y1, int x2, int y2, void *buffer);

 //! puts the image pointed to by buffer to the screen
 extern void putimage(int x1, int y1, void *buffer);

 /** puts the image in pictbuffer on the screen performing a color translation.
      xlattables points to an array of n*256 byte. n must be equal or greater than the highest 
      pixel in pictbuffer.
      Example: you want to paint the tracks on the screen which are left by heavy vehicles.
        There is an image of a track which contains just pixels of 0, 1 and two. You now provide
        a set of 3 tables each 256 bytes large. The first one just counts from 0 to 255
        The second one has color values that are a bit darker than the original: If color #2 was
        blue, table[2] would have the index of a dark blue color.
        The third table is like the second one, but points to even darker colors.
        If you now paint the track using this function:
           where there is color #0 in the track image, the pixel on the screen would be unchanged
           where there is color #1 in the track image, the pixel on the screen is made darker
           and where there is color #2, the pixel on the screen is becoming even more darker
      Ok, that's all. A very specialized function. I just checked and noticed that it is not used
      any more by ASC. Damn, why did I write this description instead of just deleting this
      procedure ;-)
 */
 extern void putxlatfilter ( int x1, int y1, void* pictbuffer, char* xlattables );

 //! puts the image pointed to by buffer on the screen. All pixels with color #255 are treated as transparent
 extern void putspriteimage(int x1, int y1, void *buffer);

 /** like #putspriteimage, but all color with an 16 <= colorIndex <= 23 are increased by 
      rotationvalue. This is used to display colored units. The mentioned color range are the
      red colors, which can be made blue by adding 8 to them, 16 makes them brown, etc.. */
 extern void putrotspriteimage(int x1, int y1, void *buffer, int rotationvalue);

 //! like #putspriteimage, but rotates the image by 90 clock-wise
 extern void putrotspriteimage90(int x1, int y1, void *buffer, int rotationvalue);

 //! like #putspriteimage, but rotates the image by 180 clock-wise
 extern void putrotspriteimage180(int x1, int y1, void *buffer, int rotationvalue);

 //! like #putspriteimage, but rotates the image by 270 clock-wise
 extern void putrotspriteimage270(int x1, int y1, void *buffer, int rotationvalue);

 //! function not used any more and obsolete. Use #putimageprt instead
 extern void puttexture ( int x1, int y1, int x2, int y2, void *texture );

 /** Puts a part of texture on the screen. Texture must be the same size as the screen,
      so the coordinates x1/y1 and x2/y2 describe the same rectangle on texture and the screen.
      This rectangle is copied from texture to the screen. color #255 is treated as transparent */
 extern void putspritetexture ( int x1, int y1, int x2, int y2, void *texture );

 /** copies a part of texture to the screen. Texture and the screen may have different size.
      x1/y1 and x2/y2 is the rectangle of the screen that texture is copied to. 
      dx/dy is the offset between x1/y1 and the upper left corner of texture.
      If dx==0 and dy==1, the uppermost line of texture would not be displayed.
      The rectangle x1/y1 - x2/y2 may be larger than texture.                   */
 extern void putimageprt ( int x1, int y1, int x2, int y2, void *texture, int dx, int dy );

#if 0
 /** Performs a color translation of the image pntr. The image is not modified. The new image
      is written to a static buffer. The address of the buffer is returned. The call to xlatpict
      will overwrite the buffer. The conversion itself will replace color by xl[color]    */
 extern void* xlatpict ( ppixelxlattable xl, void* pntr );
#endif

 //! returns the position of the lowest bit of a which is set. This equals an inter logarithm to the base of 2
 extern int loga2 ( int a );
 

 //! transforms the coordinate for an image rotation
 extern SPoint getPixelRotationLocation( SPoint pos, int width, int height, int degrees );


 //! puts a single pixel on the screen. This is one of the few functions that work in truecolor mode too
 extern void putpixel(int x1, int y1, int color);
 
 //! gets the color of a single pixel from the screen. This is one of the few functions that work in truecolor mode too
 extern int getpixel(int x1, int y1);

 //! returns the size for a buffer that can contain an image of the given size.
 extern int imagesize(int x1, int y1, int x2, int y2);
 
 //! write the dimension of the image p to width and height
 extern void getpicsize(void* p, int& width, int& height);

 //! returns the size that the picture p occupies in memory
 extern int  getpicsize2(void* p );

 /** uncompresses the RLE-compressed image pict. A buffer for the uncompressed image
      is allocated and returned, so it must be freed later                          */
 extern void* uncompress_rlepict ( void* pict );

 /** A translation table ( to be used by xlatpict ) is generated to translate any color of palette
      pal to its gray value. The new pixels after the translation are still to be used with the 
      palette pal. offset and size specify a range of colors that are assumed to be a linear
      transition from white to black. So all colors are mapped to one of the colors of the
      offset-size range. */
 extern void  generategrayxlattable( ppixelxlattable tab, Uint8 offset, Uint8 size, dacpalette256* pal );

#if 0
 /** puts a shadow of an image on the screen. This is done by replacing all pixels on the screen
      by xl[pixel] if the pixel of the image ptr is non-transparent. The actual color of the image
      does not matter. */
 extern void putshadow ( int x1, int y1, void* ptr, ppixelxlattable xl  );
#endif


/** paints a pseudo-3D rectangle on the screen. invers specifies wheather the rectangle
     seems to be pressed into the screen or coming out  */
extern void         rahmen( bool invers, int x1, int y1, int x2, int y2);

//! draws a simple line on the screen. Not very fast...
extern void         line(int x1, int y1, int x2, int y2, Uint8 color );

/** draws a simple line on the screen, but performs a XOR operation between the pixel already 
     on screen and color. Thus the line will always have a color different then the one
     that was previously there. And it can be undone by displaying it a second time. */
extern void xorline( int x1, int y1, int x2, int y2, Uint8 color );

//! draws a simple rectangl
extern void rectangle(int x1, int y1, int x2, int y2, Uint8 color );

/** draws a simple rectangle on the screen, but performs a XOR operation between the pixel already
     on screen and color. Thus the rectangle will always have a color different then the one
     that was previously there. And it can be undone by displaying it a second time. */
extern void  xorrectangle(int x1, int y1, int x2, int y2, Uint8 color) ;

//! obsolete. not used any more. can be removed.
void putinterlacedrotimage ( int x1, int y1, void* ptr, int rotation );

/** rotates the image s by 90 clockwise and writes it to d. d must point to a buffer
     with the size of imagesize2(s)                    */
void rotatepict90 ( void* s, void* d );

/** mirrors a picture horizontally (dir=1) or vertically (dir=0). d must point to a buffer
     with the size of imagesize2(s)                                  */
void flippict ( void* s, void* d, int dir = 1 );

/** reduces a pictures size. The new picture will have half the size in x and y direction, 
     resulting in a quarting of the area. The new image will be written to a static buffer that
     is overwritten the next time halfpict or xlatpict is called. The address of the buffer is
     returned.                                                                 */
void* halfpict ( void* vbuf );


/** rotates the picture image by angle clockwise. The resulting image will have exactly the
    same size as the original image, resulting in the image being clipped      */
Uint8* rotatepict ( void* image, int angle );


/** rotates the picture image by angle clockwise. The resulting image will be larger
    than the original one   */
Uint8* rotatepict_grw ( void* image, int organgle );


//! returns the pixel at position x/y of the image buf or -1 if the pixel does not exist
extern int getpixelfromimage ( void* buf, int x, int y );

/** paints an ellipse on the screen that fills the rectangle x1/y1 - x2/y2.
     The thickness of the ellipse depends on tolerance. This function is just for highlighting
     elements on the screen, not for drawing nice and mathematically correct ellipse    */
extern void ellipse ( int x1, int y1, int x2, int y2, int color, float tolerance );

//! puts an image on the screen , with all pixels of newtransparence treated as transparent.
extern void putmask ( int x1, int y1, void* vbuf, int newtransparence );

/** puts the image ptr on the screen, mixing it with the colors there. Mixbuf must point to 
     256*256 byte large structure, where mixbuf[a][b] contains the colors that results from
     mixing a and b.                  */
extern void putpicturemix ( int x1, int y1, void* ptr, int rotation, char* mixbuf );


/** when using SDL, all operations are not performed on the displaymemory itself (as is the 
     case with DOS), but on a buffer. This function copies the buffer to the screen, performing 
     a color conversion if necessary */
extern void copySurface2screen( void );
extern void copySurface2screen( int x1, int y1, int x2, int y2 );



/** An abstract class that draws a line. This can not only be used for drawing a straight line
     on the screen, but also on the gamemap for example */
class tdrawline {
         public: 
           void start ( int x1, int y1, int x2, int y2 );
           virtual void putpix ( int x, int y ) = 0;
           virtual ~tdrawline() {};
       };

/** A virtual screen is allocated and the agmp pointer set to it. All graphic operations will
     operate on this virtual display until it is deleted              */
class tvirtualdisplay {
           Surface* surface;
           void* buf;
           tgraphmodeparameters oldparams;
           void init ( int x, int y, int col, int depth );
        public: 
           tvirtualdisplay ( int x, int y );
           tvirtualdisplay ( int x, int y, int color, int depth= 8 );
           Surface& getSurface();
           ~tvirtualdisplay ();
        };



/**************************************************************
The following routines were an early attempt at rewriting the graphic engine. 
It was never continued and the routines are hardly used at all.
They can be completely scrapped should the graphic engine be rewritten 
sometime...
***************************************************************/

//! A class for a single pixel. 
struct trgbpixel {
       public:
         union {
            int rgb;
            #if SDL_BYTEORDER == SDL_LIL_ENDIAN
            struct { Uint8 r,g,b,a;  }channel;
            #else
            struct { Uint8 a,b,g,r;  }channel;
            #endif
          };
       //    mix ( const trgbpixel* pix );
          bool isTransparent();
        };

#define alphabase 64

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define TCalpha 0xfefefe
#else
#define TCalpha 0xfefefe
#endif

//! A class for a RGB image. Was an attempt to rewrite the graphics engine, but should be scrapped. Any new code should use SDLmm-Surfaces.
class TrueColorImage {
         int xsize;
         int ysize;
         trgbpixel* pix;
      public:
         TrueColorImage ( int x, int y );
         trgbpixel getpix ( int x, int y );
         trgbpixel* getpix ( void );
         void setpix ( int x, int y, int r, int g, int b, int alpha = 0 );
         void setpix ( int x, int y, const trgbpixel& pix );
         int getxsize( void );
         int getysize( void );

         ~TrueColorImage();

   };

/** the truecolor image img is reduced to 8 bit color using the palette pal. A new buffer is 
     allocated and returned. It must be freed after use.          */
extern char* convertimage ( TrueColorImage* img, dacpalette256 pal );

/** a table to speed up conversion from truecolor to 8bit palette. The 6 most significant bits
     of each color component (RGB) form the the index.       */
// extern Uint8 truecolor2pal_table[262144];

//! puts the image pointed to by tci to the screen. Both must be truecolor images. This function is a quick and unoptimized hack!
extern void putimage ( int x1, int y1, TrueColorImage* tci );
extern void putimage_noalpha ( int x1, int y1, TrueColorImage* tci );

TrueColorImage* smoothimage ( TrueColorImage* src );


extern TrueColorImage* getimage(int x1, int y1, int x2, int y2 );


//! a class that is thrown as exception. Should be moved to error.h ...
class fatalgraphicserror { 
        char st[1000];
      public:
        fatalgraphicserror ( const char* strng );
        fatalgraphicserror ( void );
      };

/** \brief Collects all graphic operations and updates the screen on destruction
     When porting ASC from DOS to SDL, the problem arose that under DOS all graphic operations
     directly modified the graphics memory and were directly visible without any overhead. Using
     SDL, the operations operated on a buffer that had to be copied to display memory in a 
     seperate operation, which was costly. Updating the screen after every basic graphic operation
     was too expensive, so I wrote this class that suspended all updates until it was destructed. */
class collategraphicoperations {
         int olddirectscreenaccess;
         int x1, y1, x2, y2;
         int status;
       public:
         collategraphicoperations ( void );
         collategraphicoperations ( int _x1, int _y1, int _x2, int _y2 );
         ~collategraphicoperations ();
         void on ( void );
         void off ( void );
};



#pragma pack()

// this variable determines whether the next call to initgraphics will open a window or a fullscreen session
// extern int fullscreen;

//! sets the caption of the main window
extern void setWindowCaption ( const char* s );

#ifdef use_truecolor2pal
/** converts a SDLmm::Surface to an old style image buffer
    \param s The source surface
    \param paletteTranslation If the source surface is 8 bit, convertSurface will convert the palette to the ASC palette if this is set to true.
*/
extern void* convertSurface ( SDLmm::Surface& s, bool paletteTranslation = true );
#endif

extern SPoint getPixelRotationLocation( SPoint pos, int width, int height, int degrees );

#endif