Merge remote branch 'origin/master' into newnet

Conflicts:
	configure.ac
master
Cyp 2010-07-16 18:01:22 +02:00
commit 23cbd537f7
15 changed files with 213 additions and 162 deletions

View File

@ -214,39 +214,40 @@ AX_C_CHECK_FLAG([-Werror -Wno-enum-compare], , , CFLAGS_IGNORE_WARNINGS="${CFLAG
if test "x$enable_debug" = "xyes" ; then
if test "x$cc_icc" = "xyes" ; then
WZ_CFLAGS="${WZ_CFLAGS} -O0 -g -fp-model precise -fp-model source -ftz -no-fma -Wcheck -Werror"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -O0 -g -fp-model precise -fp-model source -ftz -no-fma -Wcheck -Werror"
# "-fp-model precise -fp-model source -ftz -no-fma" was here
WZ_CFLAGS="${WZ_CFLAGS} -O0 -g -Wcheck -Werror"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -O0 -g -Wcheck -Werror"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DDEBUG"
else
# -mno-fused-madd = Do not generate fused multiply-add instructions, which round differently than separate multiply and add instructions.
# "-mno-fused-madd" was here
WZ_WARNINGS="-Wall -Werror -Wno-unused-label -Wmissing-field-initializers -Wcast-align -Wwrite-strings -Wmissing-declarations -Wpointer-arith -Wno-format-security"
WZ_CFLAGS="${WZ_CFLAGS} -O0 -g -mno-fused-madd -Wno-pointer-to-int-cast -Wstrict-prototypes -Wdeclaration-after-statement ${WZ_WARNINGS} ${CFLAGS_IGNORE_WARNINGS}"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -O0 -g -mno-fused-madd -Wextra ${WZ_WARNINGS}"
WZ_CFLAGS="${WZ_CFLAGS} -O0 -g -Wno-pointer-to-int-cast -Wstrict-prototypes -Wdeclaration-after-statement ${WZ_WARNINGS} ${CFLAGS_IGNORE_WARNINGS}"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -O0 -g -Wextra ${WZ_WARNINGS}"
WZ_C99FLAGS="${WZ_C99FLAGS} -Wno-declaration-after-statement"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DDEBUG"
fi
elif test "x$enable_debug" = "xrelaxed" ; then
WZ_CFLAGS="${WZ_CFLAGS} -g -O0 -mno-fused-madd -Wall -Wextra -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O0 -mno-fused-madd -Wall -Wextra -Wwrite-strings"
WZ_CFLAGS="${WZ_CFLAGS} -g -O0 -Wall -Wextra -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O0 -Wall -Wextra -Wwrite-strings"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DDEBUG"
elif test "x$enable_debug" = "xdebugprofile" ; then
WZ_CFLAGS="${WZ_CFLAGS} -g -O0 -pg -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O0 -pg -mno-fused-madd -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O0 -pg -Wall -Wwrite-strings"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DDEBUG"
LDFLAGS="-pg ${LDFLAGS}"
elif test "x$enable_debug" = "xprofile" ; then
WZ_CFLAGS="${WZ_CFLAGS} -g -Os -pg -mno-fused-madd -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -Os -pg -mno-fused-madd -Wall -Wwrite-strings"
WZ_CFLAGS="${WZ_CFLAGS} -g -Os -pg -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -Os -pg -Wall -Wwrite-strings"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DNDEBUG"
LDFLAGS="-pg ${LDFLAGS}"
elif test "x$enable_debug" = "xg++" ; then
WZ_CFLAGS="${WZ_CFLAGS} -g -O2 -mno-fused-madd -Wall -fpermissive"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O2 -mno-fused-madd -Wall"
WZ_CFLAGS="${WZ_CFLAGS} -g -O2 -Wall -fpermissive"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -O2 -Wall"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DDEBUG"
CC="g++"
else
WZ_CFLAGS="${WZ_CFLAGS} -g -mno-fused-madd -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -mno-fused-madd -Wall -Wwrite-strings"
WZ_CFLAGS="${WZ_CFLAGS} -g -Wall -Wwrite-strings"
WZ_CXXFLAGS="${WZ_CXXFLAGS} -g -Wall -Wwrite-strings"
WZ_CPPFLAGS="${WZ_CPPFLAGS} -DNDEBUG"
fi

View File

@ -380,20 +380,17 @@ void inputHandleMouseMotionEvent(SDL_MouseMotionEvent * motionEvent)
switch (motionEvent->type)
{
case SDL_MOUSEMOTION:
if(!mouseDown(MOUSE_MMB))
{
/* store the current mouse position */
mouseXPos = motionEvent->x;
mouseYPos = motionEvent->y;
/* store the current mouse position */
mouseXPos = motionEvent->x;
mouseYPos = motionEvent->y;
/* now see if a drag has started */
if ( ( aMouseState[dragKey].state == KEY_PRESSED ||
aMouseState[dragKey].state == KEY_DOWN )
&& ( ABSDIF(dragX, mouseXPos) > DRAG_THRESHOLD ||
ABSDIF(dragY, mouseYPos) > DRAG_THRESHOLD ) )
{
aMouseState[dragKey].state = KEY_DRAG;
}
/* now see if a drag has started */
if ((aMouseState[dragKey].state == KEY_PRESSED ||
aMouseState[dragKey].state == KEY_DOWN) &&
(ABSDIF(dragX, mouseXPos) > DRAG_THRESHOLD ||
ABSDIF(dragY, mouseYPos) > DRAG_THRESHOLD))
{
aMouseState[dragKey].state = KEY_DRAG;
}
break;
default:
@ -495,7 +492,10 @@ Uint16 mouseY(void)
/* This returns true if the mouse key is currently depressed */
bool mouseDown(MOUSE_KEY_CODE code)
{
return (aMouseState[code].state != KEY_UP);
return (aMouseState[code].state != KEY_UP) ||
// holding down LMB and RMB counts as holding down MMB
(code == MOUSE_MMB && aMouseState[MOUSE_LMB].state != KEY_UP && aMouseState[MOUSE_RMB].state != KEY_UP);
}
/* This returns true if the mouse key was double clicked */
@ -523,7 +523,11 @@ bool mouseReleased(MOUSE_KEY_CODE code)
/* Check for a mouse drag, return the drag start coords if dragging */
bool mouseDrag(MOUSE_KEY_CODE code, UDWORD *px, UDWORD *py)
{
if (aMouseState[code].state == KEY_DRAG)
if ((aMouseState[code].state == KEY_DRAG) ||
// dragging LMB and RMB counts as dragging MMB
(code == MOUSE_MMB && ((aMouseState[MOUSE_LMB].state == KEY_DRAG && aMouseState[MOUSE_RMB].state != KEY_UP) ||
(aMouseState[MOUSE_LMB].state != KEY_UP && aMouseState[MOUSE_RMB].state == KEY_DRAG))))
{
*px = dragX;
*py = dragY;

View File

@ -731,7 +731,7 @@ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *
// if(psEdBox->pFontDisplay) {
// psEdBox->pFontDisplay(fx,fy, pPrint);
// } else {
iV_DrawText(utf, fx, fy);
iV_DrawText(utf, fx, fy+2);
// }
free(utf);
*pInsPoint = ch;

View File

@ -231,7 +231,16 @@ BOOL loadConfig(void)
setRightClickOrders(false);
setWarzoneKeyNumeric("RightClickOrders", false);
}
if (getWarzoneKeyNumeric("MiddleClickRotate", &val))
{
setMiddleClickRotate(val);
}
else
{
setMiddleClickRotate(false);
setWarzoneKeyNumeric("MiddleClickRotate", false);
}
// //////////////////////////
// rotate radar
if(getWarzoneKeyNumeric("rotateRadar", &val))
@ -730,6 +739,7 @@ BOOL saveConfig(void)
setWarzoneKeyNumeric("shake",(SDWORD)(getShakeStatus())); // screenshake
setWarzoneKeyNumeric("mouseflip",(SDWORD)(getInvertMouseStatus())); // flipmouse
setWarzoneKeyNumeric("RightClickOrders",(SDWORD)(getRightClickOrders()));
setWarzoneKeyNumeric("MiddleClickRotate",(SDWORD)(getMiddleClickRotate()));
setWarzoneKeyNumeric("shadows",(SDWORD)(getDrawShadows())); // shadows
setWarzoneKeyNumeric("sound", (SDWORD)war_getSoundEnabled());
setWarzoneKeyNumeric("FMVmode",(SDWORD)(war_GetFMVmode())); // sequences

View File

@ -653,6 +653,11 @@ void displayConsoleMessages( void )
MesY = iV_DrawFormattedText(psMessage->text, mainConsole.topX, MesY,
mainConsole.width, psMessage->JustifyType);
if (!bTextBoxActive)
{
MesY -= 3; // make them fit inside the chat box
}
/* Move on */
++numProcessed;
}

View File

@ -177,6 +177,7 @@ static BOOL anyDroidSelected(UDWORD player);
static BOOL cyborgDroidSelected(UDWORD player);
static BOOL bInvertMouse = true;
static BOOL bRightClickOrders = false;
static BOOL bMiddleClickRotate = false;
static BOOL bDrawShadows = true;
static SELECTION_TYPE establishSelection(UDWORD selectedPlayer);
static void dealWithLMB( void );
@ -272,6 +273,7 @@ void setInvertMouseStatus( BOOL val )
#define MOUSE_ORDER (bRightClickOrders?MOUSE_RMB:MOUSE_LMB)
#define MOUSE_SELECT (bRightClickOrders?MOUSE_LMB:MOUSE_RMB)
#define MOUSE_ROTATE (bMiddleClickRotate?MOUSE_MMB:MOUSE_RMB)
BOOL getRightClickOrders( void )
{
@ -284,6 +286,17 @@ void setRightClickOrders( BOOL val )
}
BOOL getMiddleClickRotate( void )
{
return bMiddleClickRotate;
}
void setMiddleClickRotate( BOOL val )
{
bMiddleClickRotate = val;
}
BOOL getDrawShadows( void )
{
return(bDrawShadows);
@ -549,7 +562,7 @@ static void CheckFinishedDrag(void)
return;
}
if (mouseReleased(MOUSE_LMB))
if (mouseReleased(MOUSE_LMB) || mouseDown(MOUSE_RMB))
{
selectAttempt = false;
if(dragBox3D.status == DRAG_DRAGGING)
@ -800,7 +813,7 @@ void processMouseClickInput(void)
kill3DBuilding();
bRadarDragging = false;
}
if (mouseDrag(MOUSE_RMB,(UDWORD *)&rotX,(UDWORD *)&rotY) && !rotActive && !bRadarDragging)
if (mouseDrag(MOUSE_ROTATE,(UDWORD *)&rotX,(UDWORD *)&rotY) && !rotActive && !bRadarDragging)
{
rotInitial = player.r.y;
rotInitialUp = player.r.x;
@ -1320,7 +1333,7 @@ void displayWorld(void)
shakeUpdate();
if (mouseDown(MOUSE_RMB) && rotActive)
if (mouseDown(MOUSE_ROTATE) && rotActive)
{
if (abs(mouseX() - rotX) > 2 || xMoved > 2 || abs(mouseY() - rotY) > 2 || yMoved > 2)
{
@ -1369,7 +1382,7 @@ void displayWorld(void)
}
}
if(mouseReleased(MOUSE_RMB) && rotActive)
if (!mouseDown(MOUSE_ROTATE) && rotActive)
{
rotActive = false;
xMoved = yMoved = 0;

View File

@ -63,6 +63,9 @@ extern BOOL getInvertMouseStatus( void );
extern void setRightClickOrders( BOOL val );
extern BOOL getRightClickOrders( void );
extern void setMiddleClickRotate( BOOL val );
extern BOOL getMiddleClickRotate( void );
extern void setDrawShadows( BOOL val );
extern BOOL getDrawShadows( void );

View File

@ -995,6 +995,18 @@ static BOOL startMouseOptionsMenu(void)
addTextButton(FRONTEND_MBUTTONS_R, FRONTEND_POS2M-25, FRONTEND_POS5Y, _("Off"), 0);
}
////////////
// middle-click rotate
addTextButton(FRONTEND_MMROTATE, FRONTEND_POS2X-35, FRONTEND_POS6Y, _("Rotate Screen"), 0);
if( getMiddleClickRotate() )
{ // right-click orders
addTextButton(FRONTEND_MMROTATE_R, FRONTEND_POS2M-25, FRONTEND_POS6Y, _("Middle Mouse"), 0);
}
else
{ // left-click orders
addTextButton(FRONTEND_MMROTATE_R, FRONTEND_POS2M-25, FRONTEND_POS6Y, _("Right Mouse"), 0);
}
// Add some text down the side of the form
addSideText(FRONTEND_SIDETEXT, FRONTEND_SIDEX, FRONTEND_SIDEY, _("MOUSE OPTIONS"));
@ -1066,6 +1078,20 @@ BOOL runMouseOptionsMenu(void)
}
break;
case FRONTEND_MMROTATE:
case FRONTEND_MMROTATE_R:
if( getMiddleClickRotate() )
{
setMiddleClickRotate(false);
widgSetString(psWScreen,FRONTEND_MMROTATE_R, _("Right Mouse"));
}
else
{
setMiddleClickRotate(true);
widgSetString(psWScreen,FRONTEND_MMROTATE_R, _("Middle Mouse"));
}
break;
case FRONTEND_QUIT:
changeTitleMode(OPTIONS);
break;

View File

@ -233,6 +233,8 @@ enum
FRONTEND_MFLIP_R,
FRONTEND_MBUTTONS,
FRONTEND_MBUTTONS_R,
FRONTEND_MMROTATE,
FRONTEND_MMROTATE_R,
FRONTEND_KEYMAP = 26000, // Keymap menu
FRONTEND_NOGAMESAVAILABLE = 31666 // Used when no games are available in lobby

View File

@ -2887,7 +2887,7 @@ void intDisplayStatsBar(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, WZ_DEC
/* draw text value */
sprintf(szVal, "%d", BarGraph->iOriginal);
iV_SetTextColour(WZCOL_TEXT_BRIGHT);
iV_DrawText( szVal, x0, iY );
iV_DrawText( szVal, x0, iY+2 );
//draw the comparison value - only if not zero
if (BarGraph->minorSize != 0)
@ -2944,7 +2944,7 @@ void intDisplayDesignPowerBar(WIDGET *psWidget, UDWORD xOffset,
/* draw text value */
sprintf(szVal, "%d", BarGraph->iOriginal);
iV_SetTextColour(WZCOL_TEXT_BRIGHT);
iV_DrawText( szVal, x0, iY );
iV_DrawText( szVal, x0, iY+2 );
//draw the comparison value - only if not zero
if (BarGraph->minorSize != 0)

View File

@ -142,13 +142,13 @@ void lev_error(const char* msg)
LEVEL_DATASET* levFindDataSet(const char* name)
{
LEVEL_DATASET* psNewLevel;
LEVEL_DATASET* psCloseEnough = NULL;
for (psNewLevel = psLevels; psNewLevel; psNewLevel = psNewLevel->psNext)
{
if (psNewLevel->pName != NULL)
{
if (strcmp(psNewLevel->pName, name) == 0 ||
(strncmp(psNewLevel->pName, "Sk-", 3) == 0 &&
if ((strncmp(psNewLevel->pName, "Sk-", 3) == 0 &&
strcmp(psNewLevel->pName+3, name) == 0) ||
(strncmp(psNewLevel->pName, "Sk-", 3) == 0 &&
strcmp(psNewLevel->pName+strlen(name)-3-3, "-T1") &&
@ -156,10 +156,14 @@ LEVEL_DATASET* levFindDataSet(const char* name)
{
return psNewLevel;
}
if (strcmp(psNewLevel->pName, name) == 0)
{
psCloseEnough = psNewLevel;
}
}
}
return NULL;
return psCloseEnough;
}
// parse a level description data file

View File

@ -25,9 +25,6 @@
*/
#include "lib/framework/frame.h"
#include <float.h>
#include <math.h>
#include "lib/framework/trig.h"
#include "lib/framework/math_ext.h"
#include "lib/gamelib/gtime.h"
@ -1311,16 +1308,14 @@ static void moveCalcDroidSlide(DROID *psDroid, int *pmx, int *pmy)
}
// get an obstacle avoidance vector
static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY)
static void moveGetObstacleVector(DROID *psDroid, int32_t *pX, int32_t *pY)
{
SDWORD xdiff, ydiff, absx, absy, dist;
BASE_OBJECT *psObj;
SDWORD numObst = 0, distTot = 0;
float dirX = 0, dirY = 0;
float omag, ox, oy, ratio;
float avoidX, avoidY;
SDWORD mapX, mapY, tx, ty, td;
PROPULSION_STATS *psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
int32_t xdiff, ydiff, distSq;
BASE_OBJECT * psObj;
int32_t numObst = 0, distTot = 0;
int32_t dirX = 0, dirY = 0;
int32_t mapOX, mapOY, mapX, mapY;
PROPULSION_STATS * psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
ASSERT(psPropStats, "invalid propulsion stats pointer");
@ -1348,107 +1343,80 @@ static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY)
// don't avoid people on the other side - run over them
continue;
}
xdiff = (SDWORD)psObj->pos.x - (SDWORD)psDroid->pos.x;
ydiff = (SDWORD)psObj->pos.y - (SDWORD)psDroid->pos.y;
if ((float)xdiff * *pX + (float)ydiff * *pY < 0)
xdiff = psObj->pos.x - psDroid->pos.x;
ydiff = psObj->pos.y - psDroid->pos.y;
if (xdiff * *pX + ydiff * *pY < 0)
{
// object behind
continue;
}
absx = labs(xdiff);
absy = labs(ydiff);
dist = absx > absy ? absx + absy/2 : absx/2 + absy;
distSq = xdiff*xdiff + ydiff*ydiff + 1;
if (dist != 0)
{
dirX += (float)xdiff / (float)(dist * dist);
dirY += (float)ydiff / (float)(dist * dist);
distTot += dist*dist;
numObst += 1;
}
else
{
dirX += xdiff;
dirY += ydiff;
numObst += 1;
}
dirX += xdiff * 65536 / distSq;
dirY += ydiff * 65536 / distSq;
distTot += distSq;
numObst += 1;
}
// now scan for blocking tiles
mapX = map_coord(psDroid->pos.x);
mapY = map_coord(psDroid->pos.y);
for(ydiff=-2; ydiff<=2; ydiff++)
mapOX = map_coord(psDroid->pos.x);
mapOY = map_coord(psDroid->pos.y);
for (mapY = mapOY - 2; mapY <= mapOY + 2; ++mapY)
{
for(xdiff=-2; xdiff<=2; xdiff++)
for (mapX = mapOX - 2; mapX <= mapOX + 2; ++mapX)
{
if ((float)xdiff * *pX + (float)ydiff * *pY <= 0)
xdiff = world_coord(mapX) + TILE_UNITS/2 - psDroid->pos.x;
ydiff = world_coord(mapY) + TILE_UNITS/2 - psDroid->pos.y;
if (xdiff * *pX + ydiff * *pY <= 0)
{
// object behind
continue;
}
if (fpathBlockingTile(mapX + xdiff, mapY + ydiff, psPropStats->propulsionType))
if (fpathBlockingTile(mapX, mapY, psPropStats->propulsionType))
{
tx = world_coord(xdiff);
ty = world_coord(ydiff);
td = tx*tx + ty*ty;
if (td < AVOID_DIST*AVOID_DIST)
distSq = xdiff*xdiff + ydiff*ydiff + 1;
if (distSq < AVOID_DIST*AVOID_DIST)
{
absx = labs(tx);
absy = labs(ty);
dist = absx > absy ? absx + absy/2 : absx/2 + absy;
if (dist != 0)
{
dirX += (float)tx / (float)(dist * dist);
dirY += (float)ty / (float)(dist * dist);
distTot += dist*dist;
numObst += 1;
}
dirX += xdiff * 65536 / distSq;
dirY += ydiff * 65536 / distSq;
distTot += distSq;
numObst += 1;
}
}
}
}
if (numObst > 0)
if (dirX != 0 || dirY != 0)
{
int32_t avoidX, avoidY;
int32_t ox, oy;
int32_t dist;
int64_t ratio;
distTot /= numObst;
// Create the avoid vector
if (dirX == 0 && dirY == 0)
dist = iHypot(dirX, dirY);
ox = (int64_t)dirX * 65536 / dist;
oy = (int64_t)dirY * 65536 / dist;
if (*pX * oy + *pY * -ox < 0)
{
avoidX = 0;
avoidY = 0;
distTot = AVOID_DIST*AVOID_DIST;
avoidX = -oy;
avoidY = ox;
}
else
{
omag = sqrtf(dirX*dirX + dirY*dirY);
ox = dirX / omag;
oy = dirY / omag;
if (*pX * oy + *pY * -ox < 0)
{
avoidX = -oy;
avoidY = ox;
}
else
{
avoidX = oy;
avoidY = -ox;
}
avoidX = oy;
avoidY = -ox;
}
// combine the avoid vector and the target vector
ratio = (float)distTot / (float)(AVOID_DIST * AVOID_DIST);
if (ratio > 1)
{
ratio = 1;
}
ratio = MIN(distTot, (AVOID_DIST * AVOID_DIST));
*pX = *pX * ratio + avoidX * (1.f - ratio);
*pY = *pY * ratio + avoidY * (1.f - ratio);
*pX = *pX * ratio / 256 + avoidX * ((AVOID_DIST * AVOID_DIST) - ratio) / 65536;
*pY = *pY * ratio / 256 + avoidY * ((AVOID_DIST * AVOID_DIST) - ratio) / 65536;
}
ASSERT(isfinite(*pX) && isfinite(*pY), "float infinity detected");
}
@ -1466,11 +1434,7 @@ static uint16_t moveGetDirection(DROID *psDroid)
// Transporters don't need to avoid obstacles, but everyone else should
if (psDroid->droidType != DROID_TRANSPORTER)
{
float fX = dest.x >> EXTRA_BITS;
float fY = dest.y >> EXTRA_BITS;
moveGetObstacleVector(psDroid, &fX, &fY);
dest.x = fX * EXTRA_PRECISION;
dest.y = fY * EXTRA_PRECISION;
moveGetObstacleVector(psDroid, &dest.x, &dest.y);
}
return iAtan2(dest.x, dest.y);

View File

@ -2072,7 +2072,7 @@ static void addChatBox(void)
enableConsoleDisplay(true);
setConsoleBackdropStatus(false);
setDefaultConsoleJust(LEFT_JUSTIFY);
setConsoleSizePos(MULTIOP_CHATBOXX+4+D_W, MULTIOP_CHATBOXY+10+D_H, MULTIOP_CHATBOXW-4);
setConsoleSizePos(MULTIOP_CHATBOXX+4+D_W, MULTIOP_CHATBOXY+14+D_H, MULTIOP_CHATBOXW-4);
setConsolePermanence(true,true);
setConsoleLineInfo(5); // use x lines on chat window

View File

@ -127,7 +127,12 @@ static BOOL checkGameWdg(const char *nm)
for (lev = psLevels; lev; lev = lev->psNext)
{
if (strcmp(lev->pName, nm) == 0)
if (strcmp(lev->pName, nm) == 0 ||
(strncmp(lev->pName, "Sk-", 3) == 0 &&
strcmp(lev->pName+3, nm) == 0) ||
(strncmp(lev->pName, "Sk-", 3) == 0 &&
strcmp(lev->pName+strlen(nm)-3-3, "-T1") &&
strncmp(lev->pName+3, nm, strlen(nm)-3) == 0))
{
return true;
}

View File

@ -93,6 +93,10 @@ static GLuint lightmap_tex_num;
static unsigned int lightmapNextUpdate;
/// How big is the lightmap?
static int lightmapSize;
/// Lightmap image
static GLubyte *lightmapPixmap;
/// Ticks per lightmap refresh
static const unsigned int LIGHTMAP_REFRESH = 80;
/// VBOs
static GLuint geometryVBO, geometryIndexVBO, textureVBO, textureIndexVBO, decalVBO;
@ -1001,7 +1005,27 @@ bool initTerrain(void)
}
debug(LOG_TERRAIN, "the size of the map is %ix%i", mapWidth, mapHeight);
debug(LOG_TERRAIN, "lightmap texture size is %ix%i", lightmapSize, lightmapSize);
// Prepare the lightmap pixmap and texture
lightmapPixmap = (GLubyte *)calloc(1, lightmapSize * lightmapSize * 3 * sizeof(GLubyte));
if (lightmapPixmap == NULL)
{
debug(LOG_FATAL, "Out of memory!");
abort();
return false;
}
glGenTextures(1, &lightmap_tex_num);
glBindTexture(GL_TEXTURE_2D, lightmap_tex_num);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, lightmapSize, lightmapSize, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmapPixmap);
terrainInitalised = true;
return true;
@ -1030,7 +1054,11 @@ void shutdownTerrain(void)
}
}
free(sectors);
glDeleteTextures(1, &lightmap_tex_num);
free(lightmapPixmap);
lightmapPixmap = NULL;
terrainInitalised = false;
}
@ -1052,18 +1080,19 @@ void drawTerrain(void)
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT | GL_DEPTH_BUFFER_BIT);
// lightmap
// we limit the framerate of the lightmap, because uploading a texture is an expensive operation
if (gameTime > lightmapNextUpdate)
{
// allocate 3D array for our lightmap--but MSVC don't support VLA's :P
unsigned char *data=(unsigned char * )malloc(lightmapSize * lightmapSize * 3 * sizeof(unsigned char));
lightmapNextUpdate = gameTime + 80;
glDeleteTextures(1, &lightmap_tex_num);
///////////////////////////////////
// set up the lightmap texture
glActiveTexture(GL_TEXTURE1);
// bind the texture
glBindTexture(GL_TEXTURE_2D, lightmap_tex_num);
glEnable(GL_TEXTURE_2D);
// we limit the framerate of the lightmap, because updating a texture is an expensive operation
if (gameTime >= lightmapNextUpdate)
{
lightmapNextUpdate = gameTime + LIGHTMAP_REFRESH;
glGenTextures(1, &lightmap_tex_num);
for (i = 0; i < lightmapSize; i++)
{
for (j = 0; j < lightmapSize; j++)
@ -1073,9 +1102,9 @@ void drawTerrain(void)
float playerX = (float)player.p.x/TILE_UNITS+visibleTiles.x/2;
float playerY = (float)player.p.z/TILE_UNITS+visibleTiles.y/2;
getColour(&colour, i, j, false);
data[(i * lightmapSize + j) * 3 + 0] = colour.byte.r;
data[(i * lightmapSize + j) * 3 + 1] = colour.byte.g;
data[(i * lightmapSize + j) * 3 + 2] = colour.byte.b;
lightmapPixmap[(i * lightmapSize + j) * 3 + 0] = colour.byte.r;
lightmapPixmap[(i * lightmapSize + j) * 3 + 1] = colour.byte.g;
lightmapPixmap[(i * lightmapSize + j) * 3 + 2] = colour.byte.b;
if (!rendStates.fogEnabled)
{
@ -1099,34 +1128,19 @@ void drawTerrain(void)
}
if (darken < 1)
{
data[(i * lightmapSize + j) * 3 + 0] *= darken;
data[(i * lightmapSize + j) * 3 + 1] *= darken;
data[(i * lightmapSize + j) * 3 + 2] *= darken;
lightmapPixmap[(i * lightmapSize + j) * 3 + 0] *= darken;
lightmapPixmap[(i * lightmapSize + j) * 3 + 1] *= darken;
lightmapPixmap[(i * lightmapSize + j) * 3 + 2] *= darken;
}
}
}
}
glBindTexture(GL_TEXTURE_2D, lightmap_tex_num);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, lightmapSize, lightmapSize, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
// once lightmap has been uploaded, we free it.
free(data);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, lightmapSize, lightmapSize, GL_RGB, GL_UNSIGNED_BYTE, lightmapPixmap);
}
///////////////////////////////////
// now set up the lightmap texture
glActiveTexture(GL_TEXTURE1);
// load the texture
glBindTexture(GL_TEXTURE_2D, lightmap_tex_num);
glEnable(GL_TEXTURE_2D);
// enable texture coord generation
glEnable(GL_TEXTURE_GEN_S); glError();
glEnable(GL_TEXTURE_GEN_T); glError();
glEnable(GL_BLEND);