~ubuntu-branches/ubuntu/lucid/warzone2100/lucid

« back to all changes in this revision

Viewing changes to src/radar.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger, Paul Wise, Christoph Egger
  • Date: 2009-06-29 17:12:52 UTC
  • mfrom: (1.1.11 upstream) (2.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090629171252-5ddnlfg3zfchrega
Tags: 2.2.1+dfsg1-1
[ Paul Wise ]
* New upstream release (Closes: #534962)
* Adjust the flex build-depends to take account of the conflict
  with all the versions of flex 2.5.34 (LP: #372872)
* Make the -music Recommends more strict, 2.1 music doesn't work
  with 2.2.
* Upstream moved the downloads to sourceforge, update the watch file
* Bump Standards-Version, no changes needed
* Drop use of dh_desktop since it no longer does anything
* Recommend the new warzone2100-video package, version 2.2 or similar
* Mention the warzone2100 crash reports in the -dbg package description

[ Christoph Egger ]
* Replace CC-2.0 graphic from cybersphinx, create a new tarball
* Add myself to uploaders

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
        This file is part of Warzone 2100.
3
3
        Copyright (C) 1999-2004  Eidos Interactive
4
 
        Copyright (C) 2005-2007  Warzone Resurrection Project
 
4
        Copyright (C) 2005-2009  Warzone Resurrection Project
5
5
 
6
6
        Warzone 2100 is free software; you can redistribute it and/or modify
7
7
        it under the terms of the GNU General Public License as published by
20
20
#include <string.h>
21
21
 
22
22
#include "lib/framework/frame.h"
23
 
#include "lib/ivis_common/piedef.h"
 
23
#include "lib/framework/fixedpoint.h"
24
24
#include "lib/ivis_common/rendmode.h"
25
25
// FIXME Direct iVis implementation include!
26
26
#include "lib/ivis_opengl/piematrix.h"
46
46
#include "intdisplay.h"
47
47
#include "texture.h"
48
48
 
49
 
#define HIT_NOTIFICATION        (GAME_TICKS_PER_SEC*2)
50
 
 
51
 
#define RADAR_DRAW_VIEW_BOX             // If defined then draw a box to show the viewing area.
52
 
#define RADAR_TRIANGLE_SIZE             8
53
 
#define RADAR_TRIANGLE_HEIGHT   RADAR_TRIANGLE_SIZE
54
 
#define RADAR_TRIANGLE_WIDTH    (RADAR_TRIANGLE_SIZE/2)
55
 
 
56
 
#define RADAR_FRAME_SKIP 10
57
 
 
58
 
static PIELIGHT colRadarAlly, colRadarMe, colRadarEnemy;
59
 
 
60
 
BOOL bEnemyAllyRadarColor = false;     //enemy/ally radar color
61
 
 
62
 
//current mini-map mode
63
 
RADAR_DRAW_MODE radarDrawMode = RADAR_MODE_DEFAULT;
64
 
 
 
49
#define HIT_NOTIFICATION        (GAME_TICKS_PER_SEC * 2)
 
50
#define RADAR_FRAME_SKIP        10
 
51
 
 
52
BOOL bEnemyAllyRadarColor = false;                      /**< Enemy/ally radar color. */
 
53
RADAR_DRAW_MODE radarDrawMode = RADAR_MODE_DEFAULT;     /**< Current mini-map mode. */
 
54
BOOL rotateRadar; ///< Rotate the radar?
 
55
 
 
56
static PIELIGHT         colRadarAlly, colRadarMe, colRadarEnemy;
65
57
static PIELIGHT         tileColours[MAX_TILES];
66
58
static UDWORD           *radarBuffer = NULL;
67
59
 
90
82
        {{254,37,37,200}}               // Player 7
91
83
};
92
84
 
93
 
static SDWORD RadarScrollX;
94
 
static SDWORD RadarScrollY;
95
 
static SDWORD RadarWidth;
96
 
static SDWORD RadarHeight;
97
 
static SDWORD RadVisWidth;
98
 
static SDWORD RadVisHeight;
99
 
static SDWORD RadarOffsetX;
100
 
static SDWORD RadarOffsetY;
101
 
static UWORD RadarZoom;
102
 
static SDWORD RadarMapOriginX;
103
 
static SDWORD RadarMapOriginY;
104
 
static SDWORD RadarMapWidth;
105
 
static SDWORD RadarMapHeight;
106
 
 
107
 
static void CalcRadarPixelSize(UWORD *SizeH,UWORD *SizeV);
108
 
static void CalcRadarScroll(UWORD boxSizeH,UWORD boxSizeV);
109
 
static void ClearRadar(UDWORD *screen);
110
 
static void DrawRadarTiles(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV);
111
 
static void DrawRadarObjects(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV);
112
 
static void DrawRadarExtras(UWORD boxSizeH, UWORD boxSizeV);
113
 
 
 
85
static SDWORD radarWidth, radarHeight, radarCenterX, radarCenterY, radarTexWidth, radarTexHeight;
 
86
static float RadarZoom;
 
87
static UDWORD radarBufferSize = 0;
 
88
 
 
89
static void DrawRadarTiles(void);
 
90
static void DrawRadarObjects(void);
 
91
static void DrawRadarExtras(float radarX, float radarY, float pixSizeH, float pixSizeV);
 
92
 
 
93
static void radarSize(float zoom)
 
94
{
 
95
        radarWidth = radarTexWidth * zoom;
 
96
        radarHeight = radarTexHeight * zoom;
 
97
        radarCenterX = pie_GetVideoBufferWidth() - BASE_GAP * 4 - MAX(radarHeight, radarWidth)/2;
 
98
        radarCenterY = pie_GetVideoBufferHeight() - BASE_GAP * 4 - MAX(radarWidth, radarHeight)/2;
 
99
        debug(LOG_WZ, "radar=(%u,%u) tex=(%u,%u) size=(%u,%u)", radarCenterX, radarCenterY, radarTexWidth, radarTexHeight, radarWidth, radarHeight);
 
100
}
114
101
 
115
102
void radarInitVars(void)
116
103
{
117
 
        RadarScrollX = 0;
118
 
        RadarScrollY = 0;
119
 
        RadarWidth = RADWIDTH;
120
 
        RadarHeight = RADHEIGHT;
121
 
        RadarOffsetX = 0;
122
 
        RadarOffsetY = 0;
123
 
        RadarZoom = 0;
 
104
        radarTexWidth = 0;
 
105
        radarTexHeight = 0;
 
106
        RadarZoom = 1.0f;
 
107
        debug(LOG_WZ, "Resetting radar zoom to %f", RadarZoom);
 
108
        radarSize(RadarZoom);
124
109
}
125
110
 
126
111
//called for when a new mission is started
127
 
void resetRadarRedraw(void)
 
112
void resetRadarRedraw()
128
113
{
129
 
        // nothing here now
 
114
        // make sure Radar buffer is correct
 
115
        resizeRadar();
130
116
}
131
117
 
132
118
BOOL InitRadar(void)
133
119
{
134
 
        radarBuffer = malloc(RADWIDTH * RADHEIGHT * sizeof(UDWORD));
135
 
        if (radarBuffer == NULL)
136
 
        {
137
 
                debug(LOG_ERROR, "Out of memory!");
138
 
                abort();
139
 
                return false;
140
 
        }
141
 
        memset(radarBuffer, 0, RADWIDTH * RADHEIGHT * sizeof(UDWORD));
142
 
 
143
120
        // Ally/enemy/me colors
144
121
        colRadarAlly = WZCOL_YELLOW;
145
122
        colRadarEnemy = WZCOL_RED;
150
127
        return true;
151
128
}
152
129
 
 
130
BOOL resizeRadar(void)
 
131
{
 
132
        if (radarBuffer)
 
133
        {
 
134
                free(radarBuffer);
 
135
        }
 
136
        radarTexWidth = scrollMaxX - scrollMinX;
 
137
        radarTexHeight = scrollMaxY - scrollMinY;
 
138
        radarBufferSize = radarTexWidth * radarTexHeight * sizeof(UDWORD);
 
139
        radarBuffer = malloc(radarBufferSize);
 
140
        if (radarBuffer == NULL)
 
141
        {
 
142
                debug(LOG_ERROR, "Out of memory!");
 
143
                abort();
 
144
                return false;
 
145
        }
 
146
        memset(radarBuffer, 0, radarBufferSize);
 
147
        RadarZoom = (float)MAX(RADWIDTH, RADHEIGHT) / (float)MAX(radarTexWidth, radarTexHeight);
 
148
        debug(LOG_WZ, "Setting radar zoom to %f", RadarZoom);
 
149
        radarSize(RadarZoom);
 
150
 
 
151
        return true;
 
152
}
153
153
 
154
154
BOOL ShutdownRadar(void)
155
155
{
161
161
        return true;
162
162
}
163
163
 
164
 
 
165
 
void SetRadarZoom(UWORD ZoomLevel)
 
164
void SetRadarZoom(float ZoomLevel)
166
165
{
167
 
        ASSERT( ZoomLevel <= MAX_RADARZOOM,"SetRadarZoom: Max radar zoom exceeded" );
168
 
 
169
 
        if (ZoomLevel != RadarZoom)
 
166
        if (ZoomLevel <= MAX_RADARZOOM && ZoomLevel >= MIN_RADARZOOM)
170
167
        {
 
168
                debug(LOG_WZ, "Setting radar zoom to %f from %f", ZoomLevel, RadarZoom);
171
169
                RadarZoom = ZoomLevel;
 
170
                radarSize(ZoomLevel);
172
171
        }
173
172
}
174
173
 
175
 
UDWORD GetRadarZoom(void)
 
174
float GetRadarZoom(void)
176
175
{
177
176
        return RadarZoom;
178
177
}
179
178
 
180
 
 
181
 
// Given a position within the radar, return a world coordinate.
182
 
//
183
 
void CalcRadarPosition(UDWORD mX,UDWORD mY,UDWORD *PosX,UDWORD *PosY)
184
 
{
185
 
        UWORD   boxSizeH,boxSizeV;
186
 
        SDWORD  sPosX, sPosY;
187
 
        SDWORD Xoffset,Yoffset;
188
 
 
189
 
        CalcRadarPixelSize(&boxSizeH,&boxSizeV);
190
 
        CalcRadarScroll(boxSizeH,boxSizeV);
191
 
 
192
 
        // Calculate where on the radar we clicked
193
 
        Xoffset=mX-RADTLX-RadarOffsetX;
194
 
        // we need to check for negative values (previously this meant that sPosX/Y were becoming huge)
195
 
        if (Xoffset<0) Xoffset=0;
196
 
 
197
 
        Yoffset=mY-RADTLY-RadarOffsetY;
198
 
        if (Yoffset<0) Yoffset=0;
199
 
 
200
 
        sPosX = ((Xoffset)/boxSizeH)+RadarScrollX+RadarMapOriginX;
201
 
        sPosY = ((Yoffset)/boxSizeV)+RadarScrollY+RadarMapOriginY;
202
 
 
 
179
/** Calculate the radar pixel sizes. Returns pixels per tile. */
 
180
static void CalcRadarPixelSize(float *SizeH, float *SizeV)
 
181
{
 
182
        *SizeH = (float)radarHeight / (float)radarTexHeight;
 
183
        *SizeV = (float)radarWidth / (float)radarTexWidth;
 
184
}
 
185
 
 
186
/** Given a position within the radar, return a world coordinate. */
 
187
void CalcRadarPosition(int mX, int mY, int *PosX, int *PosY)
 
188
{
 
189
        int             sPosX, sPosY;
 
190
        float           pixSizeH, pixSizeV;
 
191
        
 
192
        Vector2f pos;
 
193
        pos.x = mX - radarCenterX;
 
194
        pos.y = mY - radarCenterY;
 
195
        if (rotateRadar)
 
196
        {
 
197
                pos = Vector2f_Rotate2f(pos, -player.r.y/DEG(1));
 
198
        }
 
199
        pos.x += radarWidth/2.0;
 
200
        pos.y += radarHeight/2.0;
 
201
 
 
202
        if (pos.x<0 || pos.y<0 || pos.x>=radarWidth || pos.y>=radarHeight)
 
203
        {
 
204
                ASSERT(false, "clicked outside radar minimap (%d, %d) -> (%.1f,%.1f)", mX, mY, pos.x, pos.y);
 
205
                *PosX = 0;
 
206
                *PosY = 0;
 
207
                return;
 
208
        }
 
209
        CalcRadarPixelSize(&pixSizeH, &pixSizeV);
 
210
        sPosX = pos.x / pixSizeH;       // adjust for pixel size
 
211
        sPosY = pos.y / pixSizeV;
 
212
        sPosX += scrollMinX;            // adjust for scroll limits
 
213
        sPosY += scrollMinY;
 
214
 
 
215
#if REALLY_DEBUG_RADAR
 
216
        debug(LOG_ERROR, "m=(%d,%d) radar=(%d,%d) pos(%d,%d), scroll=(%u-%u,%u-%u) sPos=(%d,%d), pixSize=(%f,%f)",
 
217
              mX, mY, radarX, radarY, posX, posY, scrollMinX, scrollMaxX, scrollMinY, scrollMaxY, sPosX, sPosY, pixSizeH, pixSizeV);
 
218
#endif
 
219
 
 
220
        // old safety code -- still necessary?
203
221
        if (sPosX < scrollMinX)
204
222
        {
205
223
                sPosX = scrollMinX;
216
234
        {
217
235
                sPosY = scrollMaxY;
218
236
        }
 
237
 
219
238
        *PosX = sPosX;
220
239
        *PosY = sPosY;
221
240
}
222
241
 
223
 
 
224
 
// Calculate the radar pixel sizes.
225
 
//
226
 
static void CalcRadarPixelSize(UWORD *SizeH,UWORD *SizeV)
227
 
{
228
 
        UWORD Size = (UWORD)(1<<RadarZoom);
229
 
 
230
 
        *SizeH = Size;
231
 
        *SizeV = Size;
232
 
}
233
 
 
234
 
 
235
 
// Calculate the radar scroll positions from the current player position.
236
 
//
237
 
static void CalcRadarScroll(UWORD boxSizeH,UWORD boxSizeV)
238
 
{
239
 
        SDWORD viewX,viewY;
240
 
        SDWORD BorderX;
241
 
        SDWORD BorderY;
242
 
 
243
 
        RadarMapOriginX = scrollMinX;
244
 
        RadarMapOriginY = scrollMinY;
245
 
        RadarMapWidth = scrollMaxX- scrollMinX;
246
 
        RadarMapHeight = scrollMaxY - scrollMinY;
247
 
 
248
 
        RadVisWidth = RadarWidth;
249
 
        RadVisHeight = RadarHeight;
250
 
 
251
 
        if(RadarMapWidth < RadVisWidth/boxSizeH) {
252
 
                RadVisWidth = RadarMapWidth*boxSizeH;
253
 
                RadarOffsetX = (RadarWidth-RadVisWidth)/2;
254
 
        } else {
255
 
                RadarOffsetX = 0;
256
 
        }
257
 
 
258
 
        if(RadarMapHeight < RadVisHeight/boxSizeV) {
259
 
                RadVisHeight = RadarMapHeight*boxSizeV;
260
 
                RadarOffsetY = (RadarHeight-RadVisHeight)/2;
261
 
        } else {
262
 
                RadarOffsetY = 0;
263
 
        }
264
 
 
265
 
        BorderX = (RadVisWidth - visibleTiles.x*boxSizeH) / 2;
266
 
        BorderY = (RadVisHeight - visibleTiles.y*boxSizeV) / 2;
267
 
        BorderX /= boxSizeH;
268
 
        BorderY /= boxSizeV;
269
 
 
270
 
        if(BorderX > 16) {
271
 
                BorderX = 16;
272
 
        } else if(BorderX < 0) {
273
 
                BorderX = 0;
274
 
        }
275
 
 
276
 
        if(BorderY > 16) {
277
 
                BorderY = 16;
278
 
        } else if(BorderY < 0) {
279
 
                BorderY = 0;
280
 
        }
281
 
 
282
 
        viewX = ((player.p.x/TILE_UNITS)-RadarScrollX-RadarMapOriginX);
283
 
        viewY = ((player.p.z/TILE_UNITS)-RadarScrollY-RadarMapOriginY);
284
 
 
285
 
        if(viewX < BorderX) {
286
 
                RadarScrollX += viewX-BorderX;
287
 
        }
288
 
 
289
 
        viewX += visibleTiles.x;
290
 
        if(viewX > (RadVisWidth/boxSizeH)-BorderX) {
291
 
                RadarScrollX += viewX-(RadVisWidth/boxSizeH)+BorderX;
292
 
        }
293
 
 
294
 
        if(viewY < BorderY) {
295
 
                RadarScrollY += viewY-BorderY;
296
 
        }
297
 
 
298
 
        viewY += visibleTiles.y;
299
 
        if(viewY > (RadVisHeight/boxSizeV)-BorderY) {
300
 
                RadarScrollY += viewY-(RadVisHeight/boxSizeV)+BorderY;
301
 
        }
302
 
 
303
 
        if(RadarScrollX < 0) {
304
 
                RadarScrollX = 0;
305
 
        } else if(RadarScrollX > RadarMapWidth-(RadVisWidth/boxSizeH)) {
306
 
                RadarScrollX = RadarMapWidth-(RadVisWidth/boxSizeH);
307
 
        }
308
 
 
309
 
        if(RadarScrollY < 0) {
310
 
                RadarScrollY = 0;
311
 
        } else if(RadarScrollY > RadarMapHeight-(RadVisHeight/boxSizeV)) {
312
 
                RadarScrollY = RadarMapHeight-(RadVisHeight/boxSizeV);
313
 
        }
314
 
}
315
 
 
316
 
 
317
242
void drawRadar(void)
318
243
{
319
 
        UWORD   boxSizeH,boxSizeV;
 
244
        float   pixSizeH, pixSizeV;
320
245
        static int frameSkip = 0;
321
246
 
322
247
        ASSERT(radarBuffer, "No radar buffer allocated");
325
250
                return;
326
251
        }
327
252
 
328
 
        CalcRadarPixelSize(&boxSizeH,&boxSizeV);
329
 
        CalcRadarScroll(boxSizeH,boxSizeV);
 
253
        CalcRadarPixelSize(&pixSizeH, &pixSizeV);
330
254
 
331
 
        if(frameSkip<=0)
 
255
        if (frameSkip <= 0)
332
256
        {
333
 
                if (RadVisWidth != RadarWidth || RadVisHeight != RadarHeight)
334
 
                {
335
 
                        ClearRadar(radarBuffer);
336
 
                }
337
 
                DrawRadarTiles(radarBuffer, RADWIDTH, boxSizeH, boxSizeV);
338
 
                DrawRadarObjects(radarBuffer, RADWIDTH, boxSizeH, boxSizeV);
339
 
                pie_DownLoadRadar(radarBuffer, RADWIDTH, RADHEIGHT);
340
 
                frameSkip=RADAR_FRAME_SKIP;
 
257
                DrawRadarTiles();
 
258
                DrawRadarObjects();
 
259
                pie_DownLoadRadar(radarBuffer, radarTexWidth, radarTexHeight);
 
260
                frameSkip = RADAR_FRAME_SKIP;
341
261
        }
342
262
        frameSkip--;
343
 
 
344
 
        pie_ClipBegin(RADTLX, RADTLY, RADTLX + RADWIDTH, RADTLY + RADHEIGHT);
345
 
        iV_TransBoxFill( RADTLX,RADTLY, RADTLX + RADWIDTH, RADTLY + RADHEIGHT);
346
 
        pie_RenderRadar(RADTLX, RADTLY, RADWIDTH, RADHEIGHT);
347
 
        DrawRadarExtras(boxSizeH,boxSizeV);
348
 
        drawRadarBlips(boxSizeH, boxSizeV, RadarOffsetX, RadarOffsetY);
349
 
        pie_ClipEnd();
350
 
}
351
 
 
352
 
 
353
 
// Clear the radar buffer.
354
 
//
355
 
static void ClearRadar(UDWORD *screen)
356
 
{
357
 
        SDWORD i, j;
358
 
        UDWORD *pScr = screen;
359
 
 
360
 
        for (i = 0; i < RadarWidth; i++)
361
 
        {
362
 
                for (j = 0; j < RadarHeight; j++)
 
263
        pie_SetTranslucencyMode(TRANS_ALPHA);
 
264
        pie_MatBegin();
 
265
                pie_TRANSLATE(radarCenterX, radarCenterY, 0);
 
266
                if (rotateRadar)
363
267
                {
364
 
                        *pScr++ = WZCOL_RADAR_BACKGROUND.rgba;
 
268
                        // rotate the map
 
269
                        iV_MatrixRotateZ(player.r.y);
365
270
                }
366
 
        }
 
271
                // draw the box at the dimensions of the map
 
272
                iV_TransBoxFill(-radarWidth/2.0,
 
273
                                                -radarHeight/2.0,
 
274
                                                 radarWidth/2.0,
 
275
                                                 radarHeight/2.0);
 
276
                pie_RenderRadar(-radarWidth/2.0,
 
277
                                                -radarHeight/2.0,
 
278
                                                 radarWidth,
 
279
                                                 radarHeight);
 
280
        pie_MatBegin();
 
281
            pie_TRANSLATE(-radarWidth/2 - 1, -radarHeight/2 - 1, 0);
 
282
            DrawRadarExtras(0, 0, pixSizeH, pixSizeV);
 
283
        pie_MatEnd();
 
284
                drawRadarBlips(-radarWidth/2.0, -radarHeight/2.0, pixSizeH, pixSizeV);
 
285
        pie_MatEnd();
367
286
}
368
287
 
369
288
static PIELIGHT appliedRadarColour(RADAR_DRAW_MODE radarDrawMode, MAPTILE *WTile)
397
316
                case RADAR_MODE_HEIGHT_MAP:
398
317
                {
399
318
                        // draw radar terrain on/off feature
400
 
                        PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];
401
 
 
402
 
                        col.byte.r = (col.byte.r * 3 + WTile->height) / 4;
403
 
                        col.byte.b = (col.byte.b * 3 + WTile->height) / 4;
404
 
                        col.byte.g = (col.byte.g * 3 + WTile->height) / 4;
405
 
                        WScr = col;
 
319
                        WScr.byte.r = WScr.byte.g = WScr.byte.b = WTile->height;
406
320
                }
407
321
                break;
408
322
                case RADAR_MODE_NO_TERRAIN:
419
333
        return WScr;
420
334
}
421
335
 
422
 
// Draw the map tiles on the radar.
423
 
//
424
 
static void DrawRadarTiles(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV)
 
336
/** Draw the map tiles on the radar. */
 
337
static void DrawRadarTiles(void)
425
338
{
426
 
        MAPTILE *psTile;
427
 
        UWORD   SizeH = boxSizeH;
428
 
        UWORD   SizeV = boxSizeV;
429
 
        SDWORD  VisWidth = RadVisWidth;
430
 
        SDWORD  VisHeight = RadVisHeight;
431
 
        SDWORD  i, j, EndY = VisHeight;
432
 
        SDWORD  OffsetX = RadarOffsetX;
433
 
        SDWORD  OffsetY = RadarOffsetY;
434
 
        UDWORD  *Scr = screen + OffsetX + OffsetY * Modulus;
435
 
 
436
 
        ASSERT( (SizeV!=0) && (SizeV!=0) ,"Zero pixel size" );
437
 
 
438
 
        /* Get pointer to very first tile */
439
 
        psTile = psMapTiles + RadarScrollX + RadarScrollY*mapWidth;
440
 
        psTile += RadarMapOriginX + RadarMapOriginY*mapWidth;
441
 
 
442
 
        if(SizeH==1)
443
 
        {
444
 
                for (i=0; i<EndY; i+=SizeH)
445
 
                {
446
 
                        MAPTILE *WTile = psTile;
447
 
                        UDWORD *WScr = Scr;
448
 
 
449
 
                        for (j=0; j<VisWidth; j+=SizeV)
450
 
                        {
451
 
                                if (!getRevealStatus() || TEST_TILE_VISIBLE(selectedPlayer, WTile) || godMode)
452
 
                                {
453
 
                                        *WScr = appliedRadarColour(radarDrawMode, WTile).rgba;
454
 
                                } else {
455
 
                                        *WScr = WZCOL_RADAR_BACKGROUND.rgba;
456
 
                                }
457
 
                                /* Next pixel, next tile */
458
 
                                WScr++;
459
 
                                WTile++;
460
 
                        }
461
 
                        Scr += Modulus;
462
 
                        psTile += mapWidth;
463
 
                }
464
 
        }
465
 
        else
466
 
        {
467
 
                for (i=0; i<EndY; i+=SizeV)
468
 
                {
469
 
                        MAPTILE *WTile = psTile;
470
 
 
471
 
                        for (j=0; j<VisWidth; j+=SizeH)
472
 
                        {
473
 
                                /* Only draw if discovered or in GOD mode */
474
 
                                if (!getRevealStatus() || TEST_TILE_VISIBLE(selectedPlayer, WTile) || godMode)
475
 
                                {
476
 
                                        PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];
477
 
                                        UDWORD Val, c, d;
478
 
                                        UDWORD *Ptr = Scr + j + i * Modulus;
479
 
 
480
 
                                        col.byte.r = sqrtf(col.byte.r * WTile->illumination);
481
 
                                        col.byte.b = sqrtf(col.byte.b * WTile->illumination);
482
 
                                        col.byte.g = sqrtf(col.byte.g * WTile->illumination);
483
 
                                        Val = col.rgba;
484
 
 
485
 
                                        for(c=0; c<SizeV; c++)
486
 
                                        {
487
 
                                                UDWORD *WPtr = Ptr;
488
 
 
489
 
                                                for(d=0; d<SizeH; d++)
490
 
                                                {
491
 
                                                        *WPtr = appliedRadarColour(radarDrawMode, WTile).rgba;
492
 
                                                        WPtr++;
493
 
                                                }
494
 
                                                Ptr += Modulus;
495
 
                                        }
496
 
                                }
497
 
                                else
498
 
                                {
499
 
                                        UDWORD c, d;
500
 
                                        UDWORD *Ptr = Scr + j + i * Modulus;
501
 
 
502
 
                                        for(c=0; c<SizeV; c++)
503
 
                                        {
504
 
                                                UDWORD *WPtr = Ptr;
505
 
 
506
 
                                                for(d=0; d<SizeH; d++)
507
 
                                                {
508
 
                                                        *WPtr = WZCOL_RADAR_BACKGROUND.rgba;
509
 
                                                        WPtr++;
510
 
                                                }
511
 
                                                Ptr += Modulus;
512
 
                                        }
513
 
                                }
514
 
                                WTile++;
515
 
                        }
516
 
                        psTile += mapWidth;
 
339
        SDWORD  x, y;
 
340
 
 
341
        for (x = scrollMinX; x < scrollMaxX; x++)
 
342
        {
 
343
                for (y = scrollMinY; y < scrollMaxY; y++)
 
344
                {
 
345
                        MAPTILE *psTile = mapTile(x, y);
 
346
                        size_t pos = radarTexWidth * (y - scrollMinY) + (x - scrollMinX);
 
347
 
 
348
                        ASSERT(pos * sizeof(*radarBuffer) < radarBufferSize, "Buffer overrun");
 
349
                        if (!getRevealStatus() || TEST_TILE_VISIBLE(selectedPlayer, psTile))
 
350
                        {
 
351
                                radarBuffer[pos] = appliedRadarColour(radarDrawMode, psTile).rgba;
 
352
                        } else {
 
353
                                radarBuffer[pos] = WZCOL_RADAR_BACKGROUND.rgba;
 
354
                        }
517
355
                }
518
356
        }
519
357
}
520
358
 
521
 
 
522
 
// Draw the droids and structure positions on the radar.
523
 
//
524
 
static void DrawRadarObjects(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV)
 
359
/** Draw the droids and structure positions on the radar. */
 
360
static void DrawRadarObjects(void)
525
361
{
526
 
        SDWORD                          c,d;
527
362
        UBYTE                           clan;
528
 
        SDWORD                          x = 0, y = 0;
529
 
        DROID                           *psDroid;
530
 
        STRUCTURE                       *psStruct;
531
 
        PROXIMITY_DISPLAY       *psProxDisp;
532
 
        VIEW_PROXIMITY          *psViewProx;
533
 
        UDWORD                          *Ptr,*WPtr;
534
 
        SDWORD                          SizeH,SizeV;
535
 
        SDWORD                          bw,bh;
536
 
        SDWORD                          SSizeH,SSizeV;
537
 
        SDWORD                          VisWidth;
538
 
        SDWORD                          VisHeight;
539
 
        SDWORD                          OffsetX;
540
 
        SDWORD                          OffsetY;
541
 
        PIELIGHT                        playerCol, col;
 
363
        PIELIGHT                        playerCol;
542
364
        PIELIGHT                        flashCol;
543
 
 
544
 
        SizeH = boxSizeH;
545
 
        SizeV = boxSizeV;
546
 
        VisWidth = RadVisWidth;
547
 
        VisHeight = RadVisHeight;
548
 
        OffsetX = RadarOffsetX;
549
 
        OffsetY = RadarOffsetY;
 
365
        int                             x, y;
550
366
 
551
367
        /* Show droids on map - go through all players */
552
368
        for(clan = 0; clan < MAX_PLAYERS; clan++)
553
369
        {
 
370
                DROID           *psDroid;
 
371
 
554
372
                //see if have to draw enemy/ally color
555
373
                if (bEnemyAllyRadarColor)
556
374
                {
572
390
                flashCol = flashColours[getPlayerColour(clan)];
573
391
 
574
392
                /* Go through all droids */
575
 
                for(psDroid = apsDroidLists[clan]; psDroid != NULL;
576
 
                        psDroid = psDroid->psNext)
 
393
                for(psDroid = apsDroidLists[clan]; psDroid != NULL; psDroid = psDroid->psNext)
577
394
                {
 
395
                        if (psDroid->pos.x < world_coord(scrollMinX) || psDroid->pos.y < world_coord(scrollMinY)
 
396
                            || psDroid->pos.x >= world_coord(scrollMaxX) || psDroid->pos.y >= world_coord(scrollMaxY))
 
397
                        {
 
398
                                continue;
 
399
                        }
578
400
                        if (psDroid->visible[selectedPlayer]
579
 
                            || godMode
580
401
                            || (bMultiPlayer && game.alliance == ALLIANCES_TEAMS
581
402
                                && aiCheckAlliances(selectedPlayer,psDroid->player)))
582
403
                        {
583
 
                                x=(psDroid->pos.x/TILE_UNITS)-RadarScrollX;
584
 
                                y=(psDroid->pos.y/TILE_UNITS)-RadarScrollY;
585
 
                                x -= RadarMapOriginX;
586
 
                                y -= RadarMapOriginY;
587
 
                                x *= boxSizeH;
588
 
                                y *= boxSizeV;
589
 
 
590
 
                                {
591
 
 
592
 
                                        if((x < VisWidth) && (y < VisHeight) && (x >= 0) && (y >= 0)) {
593
 
                                                Ptr = screen + x + y*Modulus + OffsetX + OffsetY*Modulus;
594
 
 
595
 
                                                if((clan == selectedPlayer) && (gameTime-psDroid->timeLastHit < HIT_NOTIFICATION))
596
 
                                                {
597
 
                                                                col = flashCol;
598
 
                                                }
599
 
                                                else
600
 
                                                {
601
 
                                                                col = playerCol;
602
 
                                                }
603
 
 
604
 
                                                for(c=0; c<SizeV; c++)
605
 
                                                {
606
 
                                                        WPtr = Ptr;
607
 
                                                        for(d=0; d<SizeH; d++)
608
 
                                                        {
609
 
                                                                *WPtr = col.rgba;
610
 
                                                                WPtr++;
611
 
                                                        }
612
 
                                                        Ptr += Modulus;
613
 
                                                }
614
 
                                        }
 
404
                                int     x = psDroid->pos.x / TILE_UNITS;
 
405
                                int     y = psDroid->pos.y / TILE_UNITS;
 
406
                                size_t  pos = (x - scrollMinX) + (y - scrollMinY) * radarTexWidth;
 
407
 
 
408
                                ASSERT(pos * sizeof(*radarBuffer) < radarBufferSize, "Buffer overrun");
 
409
                                if (clan == selectedPlayer && gameTime-psDroid->timeLastHit < HIT_NOTIFICATION)
 
410
                                {
 
411
                                        radarBuffer[pos] = flashCol.rgba;
 
412
                                }
 
413
                                else
 
414
                                {
 
415
                                        radarBuffer[pos] = playerCol.rgba;
615
416
                                }
616
417
                        }
617
418
                }
618
419
        }
619
420
 
620
421
        /* Do the same for structures */
621
 
        for(clan = 0; clan < MAX_PLAYERS; clan++)
622
 
        {
623
 
                //see if have to draw enemy/ally color
624
 
                if (bEnemyAllyRadarColor)
625
 
                {
626
 
                        if (clan == selectedPlayer)
627
 
                        {
628
 
                                playerCol = colRadarMe;
629
 
                        }
630
 
                        else
631
 
                        {
632
 
                                playerCol = (aiCheckAlliances(selectedPlayer,clan) ? colRadarAlly: colRadarEnemy);
633
 
                        }
634
 
                }
635
 
                else
636
 
                {
637
 
                        //original 8-color mode
638
 
                        playerCol = clanColours[getPlayerColour(clan)];
639
 
                }
640
 
 
641
 
                flashCol = flashColours[getPlayerColour(clan)];
642
 
 
643
 
                /* Go through all structures */
644
 
                for(psStruct = apsStructLists[clan]; psStruct != NULL;
645
 
                        psStruct = psStruct->psNext)
646
 
                {
 
422
        for (x = scrollMinX; x < scrollMaxX; x++)
 
423
        {
 
424
                for (y = scrollMinY; y < scrollMaxY; y++)
 
425
                {
 
426
                        MAPTILE         *psTile = mapTile(x, y);
 
427
                        STRUCTURE       *psStruct = (STRUCTURE *)psTile->psObject;
 
428
                        size_t          pos = (x - scrollMinX) + (y - scrollMinY) * radarTexWidth;
 
429
 
 
430
                        ASSERT(pos * sizeof(*radarBuffer) < radarBufferSize, "Buffer overrun");
 
431
                        if (!TileHasStructure(psTile))
 
432
                        {
 
433
                                continue;
 
434
                        }
 
435
                        clan = psStruct->player;
 
436
 
 
437
                        //see if have to draw enemy/ally color
 
438
                        if (bEnemyAllyRadarColor)
 
439
                        {
 
440
                                if (clan == selectedPlayer)
 
441
                                {
 
442
                                        playerCol = colRadarMe;
 
443
                                }
 
444
                                else
 
445
                                {
 
446
                                        playerCol = (aiCheckAlliances(selectedPlayer, clan) ? colRadarAlly: colRadarEnemy);
 
447
                                }
 
448
                        } 
 
449
                        else 
 
450
                        {
 
451
                                //original 8-color mode
 
452
                                playerCol = clanColours[getPlayerColour(clan)];
 
453
                        }
 
454
                        flashCol = flashColours[getPlayerColour(clan)];
 
455
 
647
456
                        if (psStruct->visible[selectedPlayer]
648
 
                            || godMode
649
457
                            || (bMultiPlayer && game.alliance == ALLIANCES_TEAMS
650
 
                                && aiCheckAlliances(selectedPlayer,psStruct->player)))
 
458
                                && aiCheckAlliances(selectedPlayer, psStruct->player)))
651
459
                        {
652
 
                                x=(psStruct->pos.x/TILE_UNITS)-RadarScrollX;
653
 
                                y=(psStruct->pos.y/TILE_UNITS)-RadarScrollY;
654
 
                                x -= RadarMapOriginX;
655
 
                                y -= RadarMapOriginY;
656
 
                                x *= boxSizeH;
657
 
                                y *= boxSizeV;
658
 
 
659
 
        // Get structures tile size.
660
 
                                bw = (UWORD)psStruct->pStructureType->baseWidth;
661
 
                                bh = (UWORD)psStruct->pStructureType->baseBreadth;
662
 
 
663
 
        // Need to offset for the structures top left corner.
664
 
                                x -= bw >> 1;
665
 
                                y -= bh >> 1;
666
 
                                x = x&(~(boxSizeH-1));
667
 
                                y = y&(~(boxSizeV-1));
668
 
 
669
 
                                        SSizeH = (SWORD)boxSizeH*bh;
670
 
                                        SSizeV = (SWORD)boxSizeV*bw;
671
 
 
672
 
                                        // Clip the structure box.
673
 
                                        if(x < 0) {
674
 
                                                SSizeH += x;
675
 
                                                x = 0;
676
 
                                        }
677
 
 
678
 
                                        if(y < 0) {
679
 
                                                SSizeV += y;
680
 
                                                y=0;
681
 
                                        }
682
 
 
683
 
                                        if(x+SSizeH > VisWidth) {
684
 
                                                SSizeH -= (x+SSizeH) - VisWidth;
685
 
                                        }
686
 
 
687
 
                                        if(y+SSizeV > VisHeight) {
688
 
                                                SSizeV -= (y+SSizeV) - VisHeight;
689
 
                                        }
690
 
 
691
 
                                        // And draw it.
692
 
                                        if((SSizeV > 0) && (SSizeH > 0)) {
693
 
                                                Ptr = screen + x + y*Modulus + OffsetX + OffsetY*Modulus;
694
 
                                                                                        if((clan == selectedPlayer) && (gameTime - psStruct->timeLastHit < HIT_NOTIFICATION))
695
 
                                                {
696
 
                                                                col = flashCol;
697
 
                                                }
698
 
                                                else
699
 
                                                {
700
 
                                                                col = playerCol;
701
 
                                                }
702
 
 
703
 
                                                for(c=0; c<SSizeV; c++)
704
 
                                                {
705
 
                                                        WPtr = Ptr;
706
 
                                                        for(d=0; d<SSizeH; d++)
707
 
                                                        {
708
 
                                                                *WPtr = col.rgba;
709
 
                                                                WPtr++;
710
 
                                                        }
711
 
                                                        Ptr += Modulus;
712
 
                                                }
713
 
                                        }
 
460
                                if (clan == selectedPlayer && gameTime - psStruct->timeLastHit < HIT_NOTIFICATION)
 
461
                                {
 
462
                                        radarBuffer[pos] = flashCol.rgba;
 
463
                                }
 
464
                                else
 
465
                                {
 
466
                                        radarBuffer[pos] = playerCol.rgba;
 
467
                                }
714
468
                        }
715
469
                }
716
470
        }
717
 
 
718
 
        //now set up coords for Proximity Messages - but only for selectedPlayer
719
 
        for(psProxDisp = apsProxDisp[selectedPlayer]; psProxDisp != NULL;
720
 
                psProxDisp = psProxDisp->psNext)
721
 
        {
722
 
                if (psProxDisp->type == POS_PROXDATA)
723
 
                {
724
 
                        psViewProx = (VIEW_PROXIMITY *)((VIEWDATA *)psProxDisp->psMessage->
725
 
                                pViewData)->pData;
726
 
                        x = (psViewProx->x/TILE_UNITS)-RadarScrollX;
727
 
                        y = (psViewProx->y/TILE_UNITS)-RadarScrollY;
728
 
                }
729
 
                else if (psProxDisp->type == POS_PROXOBJ)
730
 
                {
731
 
                        x = (((BASE_OBJECT *)psProxDisp->psMessage->pViewData)->pos.x /
732
 
                                TILE_UNITS) - RadarScrollX;
733
 
                        y = (((BASE_OBJECT *)psProxDisp->psMessage->pViewData)->pos.y /
734
 
                                TILE_UNITS) - RadarScrollY;
735
 
                }
736
 
                x -= RadarMapOriginX;
737
 
                y -= RadarMapOriginY;
738
 
                x *= boxSizeH;
739
 
                y *= boxSizeV;
740
 
 
741
 
                        psProxDisp->radarX = 0;
742
 
                        psProxDisp->radarY = 0;
743
 
                        if((x < VisWidth) && (y < VisHeight) && (x >= 0) && (y >= 0))
744
 
                        {
745
 
                                //store the coords
746
 
                                psProxDisp->radarX = x + OffsetX;
747
 
                                psProxDisp->radarY = y + OffsetY;
748
 
                        }
749
 
        }
750
471
}
751
472
 
752
 
 
753
 
// Rotate an array of 2d vectors about a given angle, also translates them after rotating.
754
 
//
 
473
/** Rotate an array of 2d vectors about a given angle, also translates them after rotating. */
755
474
static void RotateVector2D(Vector3i *Vector, Vector3i *TVector, Vector3i *Pos, int Angle, int Count)
756
475
{
757
476
        int Cos = COS(Angle);
787
506
 
788
507
static SDWORD getLengthAdjust( void )
789
508
{
790
 
        SDWORD  pitch;
791
 
        UDWORD  lookingDown,lookingFar;
792
 
        SDWORD  dif;
793
 
 
794
 
        pitch = 360 - (player.r.x/DEG_1);
 
509
        const int pitch = 360 - (player.r.x/DEG_1);
795
510
 
796
511
        // Max at
797
 
        lookingDown = (0 - MIN_PLAYER_X_ANGLE);
798
 
        lookingFar = (0 - MAX_PLAYER_X_ANGLE);
799
 
        dif = MAX(pitch - lookingFar, 0);
 
512
        const int lookingDown = (0 - MIN_PLAYER_X_ANGLE);
 
513
        const int lookingFar = (0 - MAX_PLAYER_X_ANGLE);
 
514
 
 
515
        int dif = MAX(pitch - lookingFar, 0);
800
516
        if (dif > (lookingDown - lookingFar)) 
801
517
        {
802
518
                dif = (lookingDown - lookingFar);
805
521
        return dif / 2;
806
522
}
807
523
 
808
 
/* Draws a Myth/FF7 style viewing window */
809
 
static void drawViewingWindow(UDWORD x, UDWORD y, UDWORD pixSizeH, UDWORD pixSizeV)
 
524
/** Draws a Myth/FF7 style viewing window */
 
525
static void drawViewingWindow(float radarX, float radarY, int x, int y, float pixSizeH, float pixSizeV)
810
526
{
811
527
        Vector3i v[4], tv[4], centre;
812
528
        int     shortX, longX, yDrop, yDropVar;
831
547
        v[3].x = -shortX;
832
548
        v[3].y = yDrop;
833
549
 
834
 
        centre.x = RADTLX + x + (visibleTiles.x * pixSizeH) / 2;
835
 
        centre.y = RADTLY + y + (visibleTiles.y * pixSizeV) / 2;
 
550
        centre.x = radarX + (x - scrollMinX/2) + ((visibleTiles.x - scrollMinX) * pixSizeH) / 2;
 
551
        centre.y = radarY + (y - scrollMinY/2) + ((visibleTiles.y - scrollMinY) * pixSizeV) / 2;
836
552
 
837
553
        RotateVector2D(v,tv,&centre,player.r.y,4);
838
554
 
861
577
        }
862
578
 
863
579
        /* Send the four points to the draw routine and the clip box params */
864
 
        pie_DrawViewingWindow(tv,RADTLX,RADTLY,RADTLX+RADWIDTH,RADTLY+RADHEIGHT,colour);
 
580
        pie_DrawViewingWindow(tv, radarX, radarY, radarX + radarWidth, radarY + radarHeight, colour);
865
581
}
866
582
 
867
 
static void DrawRadarExtras(UWORD boxSizeH, UWORD boxSizeV)
 
583
static void DrawRadarExtras(float radarX, float radarY, float pixSizeH, float pixSizeV)
868
584
{
869
 
        SDWORD  viewX = ((player.p.x / TILE_UNITS) - RadarScrollX - RadarMapOriginX) * boxSizeH + RadarOffsetX;
870
 
        SDWORD  viewY = ((player.p.z / TILE_UNITS) - RadarScrollY - RadarMapOriginY) * boxSizeV + RadarOffsetY;
871
 
 
872
 
        viewX = viewX&(~(boxSizeH-1));
873
 
        viewY = viewY&(~(boxSizeV-1));
874
 
 
875
 
        drawViewingWindow(viewX, viewY, boxSizeH, boxSizeV);
876
 
        RenderWindowFrame(FRAME_RADAR, RADTLX - 1, RADTLY - 1, RADWIDTH + 2, RADHEIGHT + 2);
 
585
        int     viewX = (player.p.x / TILE_UNITS) * pixSizeH;
 
586
        int     viewY = (player.p.z / TILE_UNITS) * pixSizeV;
 
587
 
 
588
        drawViewingWindow(radarX, radarY, viewX, viewY, pixSizeH, pixSizeV);
 
589
        RenderWindowFrame(FRAME_RADAR, radarX - 1, radarY - 1, radarWidth + 2, radarHeight + 2);
877
590
}
878
591
 
879
 
// Does a screen coordinate lie within the radar area?
880
 
//
 
592
/** Does a screen coordinate lie within the radar area? */
881
593
BOOL CoordInRadar(int x,int y)
882
594
{
883
 
        if (x >= RADTLX - 1 && x < RADTLX + RADWIDTH + 1 && y >= RADTLY - 1 && y < RADTLY + RADHEIGHT + 1)
 
595
        Vector2f pos;
 
596
        pos.x = x - radarCenterX;
 
597
        pos.y = y - radarCenterY;
 
598
        if (rotateRadar)
884
599
        {
885
 
                return true;
 
600
                pos = Vector2f_Rotate2f(pos, -player.r.y/DEG(1));
886
601
        }
 
602
        pos.x += radarWidth/2;
 
603
        pos.y += radarHeight/2;
887
604
 
888
 
        return false;
 
605
        if (pos.x<0 || pos.y<0 || pos.x>=radarWidth || pos.y>=radarHeight)
 
606
        {
 
607
                return false;
 
608
        }
 
609
        return true;
889
610
}
890
611
 
891
612
void radarColour(UDWORD tileNumber, uint8_t r, uint8_t g, uint8_t b)