correct scrolling bug and cleanup(NEW_MAP_DRAW and tab)

This commit is contained in:
jarod42 2004-04-05 15:59:24 +00:00
parent d16600afe6
commit 24e9bbb014
6 changed files with 238 additions and 336 deletions

View file

@ -103,8 +103,10 @@ struct _viewport_ {
int MapWidth; /// Width in map tiles
int MapHeight; /// Height in map tiles
#ifdef NEW_MAPDRAW
char MustRedrawTile[MAXMAP_W * MAXMAP_H]; /// Must redraw tile
char MustRedrawRow[MAXMAP_W]; /// Must redraw row
#endif
Unit* Unit; /// Bound to this unit
};

View file

@ -187,50 +187,29 @@ global void RevealMap(void)
*/
global void ViewportSetViewpoint(Viewport* vp, int x, int y, int offsetx, int offsety)
{
int map_width;
int map_height;
DebugCheck(!vp);
vp->OffsetX = offsetx;
vp->OffsetY = offsety;
map_width = vp->MapWidth;
x = x * TileSizeX + offsetx;
y = y * TileSizeY + offsety;
if (x < 0) {
vp->MapX = 0;
vp->OffsetX = 0;
} else if (x >= TheMap.Width - map_width + 1) {
vp->MapX = TheMap.Width - vp->MapWidth + 1;
vp->OffsetX = 0;
} else {
vp->MapX = x;
if (vp->OffsetX < 0) {
if (vp->MapX != 0) {
vp->MapX--;
vp->OffsetX += TileSizeX;
} else {
vp->OffsetX = 0;
}
}
x = 0;
}
DebugCheck(vp->OffsetX < 0 || vp->OffsetX >= TileSizeX);
map_height = vp->MapHeight;
if (y < 0) {
vp->MapY = 0;
vp->OffsetY = 0;
} else if (y >= TheMap.Height - map_height + 1) {
vp->MapY = TheMap.Height - vp->MapHeight + 1;
vp->OffsetY = 0;
} else {
vp->MapY = y;
if (vp->OffsetY < 0) {
if (vp->MapY != 0) {
vp->MapY--;
vp->OffsetY += TileSizeY;
} else {
vp->OffsetY = 0;
}
}
y = 0;
}
DebugCheck(vp->OffsetY < 0 || vp->OffsetY >= TileSizeY);
if (x > TheMap.Width * TileSizeX - (vp->EndX - vp->X) - 1) {
x = TheMap.Width * TileSizeX - (vp->EndX - vp->X) - 1;
}
if (y > TheMap.Height * TileSizeY - (vp->EndY - vp->Y) - 1) {
y = TheMap.Height * TileSizeY - (vp->EndY - vp->Y) - 1;
}
vp->MapX = x / TileSizeX;
vp->MapY = y / TileSizeY;
vp->OffsetX = x % TileSizeX;
vp->OffsetY = y % TileSizeY;
vp->MapWidth = ((vp->EndX - vp->X) + vp->OffsetX - 1) / TileSizeX + 1;
vp->MapHeight = ((vp->EndY - vp->Y) + vp->OffsetY - 1) / TileSizeY + 1;
MarkDrawEntireMap();
MustRedraw |= RedrawMinimap | RedrawMinimapCursor;
}

View file

@ -112,7 +112,7 @@ global void VideoDrawTile(const int tile, int x, int y)
CLIP_RECTANGLE(x, y, srect.w, srect.h);
srect.x += x - oldx;
srect.y += y - oldy;
drect.x = x;
drect.y = y;
@ -227,13 +227,13 @@ global void MapDrawTile(int tile, int x, int y)
global int MarkDrawPosMap(int x, int y)
{
Viewport* vp;
if ((vp = MapTileGetViewport(x, y))) {
MustRedraw |= RedrawMap;
#if NEW_MAPDRAW
#ifdef NEW_MAPDRAW
vp->MustRedrawRow[y - vp->MapY] = 1;
vp->MustRedrawTile[x - vp->MapX + (y - vp->MapY) * vp->MapWidth] = 1;
#endif
#endif
return 1;
}
return 0;
@ -407,17 +407,19 @@ global void DrawMapBackgroundInViewport(const Viewport* vp, int x, int y)
int ex;
int dy;
int ey;
const char* redraw_row;
const char* redraw_tile;
#ifdef TIMEIT
u_int64_t sv = rdtsc();
u_int64_t ev;
static long mv = 9999999;
#endif
#ifdef NEW_MAPDRAW
const char* redraw_row;
const char* redraw_tile;
// flags must redrawn or not
redraw_row = vp->MustRedrawRow;
redraw_tile = vp->MustRedrawTile;
#endif
ex = vp->EndX;
sy = y * TheMap.Width;
@ -425,15 +427,19 @@ global void DrawMapBackgroundInViewport(const Viewport* vp, int x, int y)
ey = vp->EndY;
while (dy <= ey) {
#ifdef NEW_MAPDRAW
// row must be redrawn
if (*redraw_row++) {
#endif
sx = x + sy;
dx = vp->X - vp->OffsetX;
while (dx <= ex) {
//
// draw only tiles which must be drawn
//
#ifdef NEW_MAPDRAW
if (*redraw_tile++) {
#endif
// FIXME: unexplored fields could be drawn faster
if (ReplayRevealMap) {
MapDrawTile(TheMap.Fields[sx].Tile, dx, dy);
@ -442,7 +448,9 @@ global void DrawMapBackgroundInViewport(const Viewport* vp, int x, int y)
}
// StephanR: debug-mode denote tiles that are redrawn
#ifdef NEW_MAPDRAW
}
#endif
#ifdef NEW_MAPDRAW_
VideoDrawRectangle(redraw_tile[-1] == 1 ? ColorWhite : ColorRed,
dx, dy, 32, 32);
@ -450,6 +458,7 @@ global void DrawMapBackgroundInViewport(const Viewport* vp, int x, int y)
++sx;
dx += TileSizeX;
}
#ifdef NEW_MAPDRAW
} else {
#ifdef NEW_MAPDRAW_
sx = x + sy;
@ -462,6 +471,7 @@ global void DrawMapBackgroundInViewport(const Viewport* vp, int x, int y)
#endif
redraw_tile += vp->MapWidth;
}
#endif
sy += TheMap.Width;
dy += TileSizeY;
}

View file

@ -204,12 +204,12 @@ global int MapFogFilterFlags(Player* player, int x, int y, int mask)
int unitcount;
int fogmask;
Unit* table[UnitMax];
// Calculate Mask for tile with fog
if (x < 0 || y < 0 || x >= TheMap.Width || y >= TheMap.Height) {
return mask;
}
nunits = UnitCacheOnTile(x, y, table);
fogmask = -1;
unitcount = 0;
@ -535,7 +535,7 @@ global void VideoDrawUnexploredSDL(const int tile, int x, int y)
srect.y = TileSizeY * (tile / tilepitch);
srect.w = TileSizeX;
srect.h = TileSizeY;
oldx = x;
oldy = y;
CLIP_RECTANGLE(x, y, srect.w, srect.h);
@ -862,8 +862,6 @@ global void DrawMapFogOfWar(Viewport* vp, int x, int y)
int ex;
int dy;
int ey;
char* redraw_row;
char* redraw_tile;
int p;
int my;
int mx;
@ -875,9 +873,16 @@ global void DrawMapFogOfWar(Viewport* vp, int x, int y)
#endif
// flags must redraw or not
#ifdef NEW_MAPDRAW
char* redraw_row;
char* redraw_tile;
redraw_row = vp->MustRedrawRow;
redraw_tile = vp->MustRedrawTile;
#endif
if (ReplayRevealMap) {
return;
}
p = ThisPlayer->Player;
sx = vp->MapX - 1;
@ -896,41 +901,46 @@ global void DrawMapFogOfWar(Viewport* vp, int x, int y)
if (ey > TheMap.Height) {
ey = TheMap.Height;
}
for (; my < ey; ++my) {
// Update for visibility all tile in viewport
// and 1 tile around viewport (for fog-of-war connection display)
for (my = vp->MapY; my < ey; ++my) {
for (mx = sx; mx < ex; ++mx) {
VisibleTable[my * TheMap.Width + mx] = IsTileVisible(ThisPlayer, mx, my);
}
}
ex = vp->EndX;
sy = y * TheMap.Width;
dy = vp->Y - vp->OffsetY;
ey = vp->EndY;
while (dy <= ey) {
#ifdef NEW_MAPDRAW
// row must be redrawn
if (*redraw_row) {
#if NEW_MAPDRAW > 1
(*redraw_row)--;
#else
*redraw_row = 0;
#endif
#endif
sx = x + sy;
dx = vp->X - vp->OffsetX;
while (dx <= ex) {
#ifdef NEW_MAPDRAW
if (*redraw_tile) {
#if NEW_MAPDRAW > 1
(*redraw_tile)--;
#else
*redraw_tile = 0;
#endif
#endif
mx = (dx - vp->X + vp->OffsetX) / TileSizeX + vp->MapX;
my = (dy - vp->Y + vp->OffsetY) / TileSizeY + vp->MapY;
if (VisibleTable[my * TheMap.Width + mx] || ReplayRevealMap) {
if (VisibleTable[my * TheMap.Width + mx]) {
DrawFogOfWarTile(sx, sy, dx, dy);
} else {
VideoFillRectangleClip(ColorBlack, dx, dy, TileSizeX, TileSizeY);
}
#endif
// Used to debug NEW_FOW problems
#if defined(DEBUG_FOG_OF_WAR)
@ -962,15 +972,19 @@ extern int VideoDrawText(int x, int y, unsigned font, const unsigned char* text)
#endif
}
#endif
#ifdef NEW_MAPDRAW
}
++redraw_tile;
#endif
++sx;
dx += TileSizeX;
}
#ifdef NEW_MAPDRAW
} else {
redraw_tile += vp->MapWidth;
}
++redraw_row;
#endif
sy += TheMap.Width;
dy += TileSizeY;
}
@ -1001,7 +1015,7 @@ global void InitMapFogOfWar(void)
#else
//
// Generate Only Fog surface.
//
//
{
unsigned char r;
unsigned char g;

View file

@ -96,94 +96,6 @@ global EventCallback MenuCallbacks; /// Menu callbacks
// Functions
//----------------------------------------------------------------------------
/**
** Move map view point up (north).
**
** @param step How many pixels.
*/
local void MoveMapViewPointUp(int step)
{
Viewport* vp;
vp = TheUI.SelectedViewport;
vp->OffsetY -= step;
while (vp->OffsetY < 0) {
vp->OffsetY += TileSizeY;
--vp->MapY;
}
if (vp->MapY < 0) {
vp->MapY = 0;
vp->OffsetY = 0;
}
}
/**
** Move map view point left (west).
**
** @param step How many pixels.
*/
local void MoveMapViewPointLeft(int step)
{
Viewport* vp;
vp = TheUI.SelectedViewport;
vp->OffsetX -= step;
while (vp->OffsetX < 0) {
vp->OffsetX += TileSizeX;
--vp->MapX;
}
if (vp->MapX < 0) {
vp->MapX = 0;
vp->OffsetX = 0;
}
}
/**
** Move map view point down (south).
**
** @param step How many pixels.
*/
local void MoveMapViewPointDown(int step)
{
Viewport* vp;
vp = TheUI.SelectedViewport;
vp->OffsetY += step;
while (vp->OffsetY >= TileSizeY) {
vp->OffsetY -= TileSizeY;
++vp->MapY;
}
// If bottom is > Last map top, make it equal
if (vp->MapY + vp->MapHeight - 1 >= TheMap.Height) {
vp->MapY = TheMap.Height - vp->MapHeight + 1;
vp->OffsetY = 0;
}
}
/**
** Move map view point right (east).
**
** @param step How many pixels.
*/
local void MoveMapViewPointRight(int step)
{
Viewport* vp;
vp = TheUI.SelectedViewport;
vp->OffsetX += step;
while (vp->OffsetX >= TileSizeX) {
vp->OffsetX -= TileSizeX;
++vp->MapX;
}
// If right is > Last map top, make it equal
if (vp->MapX + vp->MapWidth - 1> TheMap.Width) {
vp->MapX = TheMap.Width - vp->MapWidth + 1;
vp->OffsetX = 0;
}
}
/**
** Handle scrolling area.
**
@ -198,8 +110,8 @@ global void DoScrollArea(enum _scroll_state_ state, int fast)
Viewport* vp;
int stepx;
int stepy;
static int remx = 0;
static int remy = 0;
static int remx = 0; // FIXME: docu
static int remy = 0; // FIXME: docu
if (state == ScrollNone) {
return;
@ -208,9 +120,9 @@ global void DoScrollArea(enum _scroll_state_ state, int fast)
vp = TheUI.SelectedViewport;
if (fast) {
stepx = TheUI.SelectedViewport->MapWidth / 2 * TileSizeX * FRAMES_PER_SECOND;
stepy = TheUI.SelectedViewport->MapHeight / 2 * TileSizeY * FRAMES_PER_SECOND;
} else { // dynamic: let these variables increase upto fast..
stepx = vp->MapWidth / 2 * TileSizeX * FRAMES_PER_SECOND;
stepy = vp->MapHeight / 2 * TileSizeY * FRAMES_PER_SECOND;
} else {// dynamic: let these variables increase upto fast..
// FIXME: pixels per second should be configurable
stepx = TileSizeX * FRAMES_PER_SECOND;
stepy = TileSizeY * FRAMES_PER_SECOND;
@ -223,6 +135,8 @@ global void DoScrollArea(enum _scroll_state_ state, int fast)
++stepx;
remx -= 100;
}
} else {
stepx = 0;
}
if (state & (ScrollUp | ScrollDown)) {
stepy = stepy * 100 * 100 / VideoSyncSpeed / FRAMES_PER_SECOND / (SkipFrames + 1);
@ -232,20 +146,18 @@ global void DoScrollArea(enum _scroll_state_ state, int fast)
++stepy;
remy -= 100;
}
} else {
stepy = 0;
}
if (state & ScrollUp) {
MoveMapViewPointUp(stepy);
stepy = -stepy;
}
if (state & ScrollLeft) {
MoveMapViewPointLeft(stepx);
}
if (state & ScrollDown) {
MoveMapViewPointDown(stepy);
}
if (state & ScrollRight) {
MoveMapViewPointRight(stepx);
stepx = -stepx;
}
ViewportSetViewpoint(vp, vp->MapX, vp->MapY,
vp->OffsetX + stepx, vp->OffsetY + stepy);
// This recalulates some values
HandleMouseMove(CursorX, CursorY);
@ -288,7 +200,6 @@ local void DrawMapViewport(Viewport* vp)
#if 0
MapUpdateFogOfWar(vp->MapX, vp->MapY);
#endif
#else
int u;
// FIXME: Johns: this didn't work correct with viewports!
@ -318,7 +229,7 @@ local void DrawMapViewport(Viewport* vp)
DrawMapBackgroundInViewport(vp, vp->MapX, vp->MapY);
//
// We find and sort units after draw level.
// We find and sort units after draw level.
//
nunits = FindAndSortUnits(vp, table);
nmissiles = FindAndSortMissiles(vp, missiletable);
@ -429,7 +340,7 @@ global void DrawMapArea(void)
}
//
// Separate the viewports and mark the active viewport.
// Separate the viewports and mark the active viewport.
//
for (vp = TheUI.Viewports; vp < evp; ++vp) {
Uint32 color;
@ -459,9 +370,9 @@ global void DrawMapArea(void)
*/
global void UpdateDisplay(void)
{
MustRedraw &= EnableRedraw; // Don't redraw disabled parts
MustRedraw &= EnableRedraw; // Don't redraw disabled parts
HideAnyCursor(); // remove cursor (when available)
HideAnyCursor(); // remove cursor (when available)
if (MustRedraw & RedrawMap) {
DrawMapArea();
@ -557,7 +468,7 @@ global void UpdateDisplay(void)
DrawAnyCursor();
//
// Update changes to display.
// Update changes to display.
//
if (MustRedraw & RedrawAll) {
// refresh entire screen, so no further invalidate needed
@ -656,8 +567,8 @@ global void UpdateDisplay(void)
}
/**
** Enable everything to be drawn for next display update.
** Used at start of mainloop (and possible refresh as user option)
** Enable everything to be drawn for next display update.
** Used at start of mainloop (and possible refresh as user option)
*/
local void EnableDrawRefresh(void)
{
@ -666,18 +577,18 @@ local void EnableDrawRefresh(void)
}
/**
** Game main loop.
** Game main loop.
**
** Unit actions.
** Missile actions.
** Players (AI).
** Cyclic events (color cycle,...)
** Display update.
** Input/Network/Sound.
** Unit actions.
** Missile actions.
** Players (AI).
** Cyclic events (color cycle,...)
** Display update.
** Input/Network/Sound.
*/
global void GameMainLoop(void)
{
#ifdef DEBUG // removes the setjmp warnings
#ifdef DEBUG // removes the setjmp warnings
static int showtip;
#else
int showtip;
@ -704,7 +615,7 @@ global void GameMainLoop(void)
showtip = 0;
RealVideoSyncSpeed = VideoSyncSpeed;
if (!IsNetworkGame()) { // Don't show them for net play
if (!IsNetworkGame()) { // Don't show them for net play
showtip = ShowTips;
}
@ -723,34 +634,33 @@ global void GameMainLoop(void)
}
#endif
//
// Game logic part
// Game logic part
//
if (!GamePaused && NetworkInSync && !SkipGameCycle) {
SinglePlayerReplayEachCycle();
++GameCycle;
MultiPlayerReplayEachCycle();
NetworkCommands(); // Get network commands
NetworkCommands(); // Get network commands
#ifdef MAP_REGIONS
MapSplitterEachCycle();
#endif // MAP_REGIONS
UnitActions(); // handle units
MissileActions(); // handle missiles
PlayersEachCycle(); // handle players
UpdateTimer(); // update game timer
UnitActions(); // handle units
MissileActions(); // handle missiles
PlayersEachCycle(); // handle players
UpdateTimer(); // update game timer
//
// Work todo each second.
// Split into different frames, to reduce cpu time.
// Increment mana of magic units.
// Update mini-map.
// Update map fog of war.
// Call AI.
// Check game goals.
// Check rescue of units.
// Work todo each second.
// Split into different frames, to reduce cpu time.
// Increment mana of magic units.
// Update mini-map.
// Update map fog of war.
// Call AI.
// Check game goals.
// Check rescue of units.
//
switch (GameCycle % CYCLES_PER_SECOND) {
case 0:
// At cycle 0, start all ai players...
case 0: // At cycle 0, start all ai players...
if (GameCycle == 0) {
for (player = 0; player < NumPlayers; ++player) {
PlayersEachSecond(player);
@ -761,16 +671,16 @@ global void GameMainLoop(void)
break;
case 2:
break;
case 3: // minimap update
case 3: // minimap update
UpdateMinimap();
MustRedraw |= RedrawMinimap;
break;
case 4:
break;
case 5: // forest grow
case 5: // forest grow
RegenerateForest();
break;
case 6: // overtaking units
case 6: // overtaking units
RescueUnits();
break;
default:
@ -784,13 +694,13 @@ global void GameMainLoop(void)
//
// Work todo each realtime second.
// Check cd-rom (every 2nd second)
// Check cd-rom (every 2nd second)
// FIXME: Not called while pause or in the user interface.
//
switch (GameCycle % ((CYCLES_PER_SECOND * VideoSyncSpeed / 100) + 1)) {
case 0: // Check cd-rom
#if defined(USE_SDLCD)
if (!(GameCycle % 4)) { // every 2nd second
if (!(GameCycle % 4)) { // every 2nd second
SDL_CreateThread(CDRomCheck, NULL);
}
#elif defined(USE_LIBCDA) || defined(USE_CDDA)
@ -805,13 +715,13 @@ global void GameMainLoop(void)
}
}
TriggersEachCycle(); // handle triggers
UpdateMessages(); // update messages
TriggersEachCycle(); // handle triggers
UpdateMessages(); // update messages
PlayListAdvance(); // Check for next song
PlayListAdvance(); // Check for next song
//
// Map scrolling
// Map scrolling
//
DoScrollArea(MouseScrollState | KeyScrollState, KeyModifiers & ModifierControl);
@ -844,8 +754,8 @@ global void GameMainLoop(void)
}
//FIXME: this might be better placed somewhere at front of the
// program, as we now still have a game on the background and
// need to go through hte game-menu or supply a pud-file
// program, as we now still have a game on the background and
// need to go through hte game-menu or supply a pud-file
UpdateDisplay();
//
@ -866,7 +776,7 @@ global void GameMainLoop(void)
WaitEventsOneFrame(Callbacks);
}
if (!NetworkInSync) {
NetworkRecover(); // recover network
NetworkRecover(); // recover network
}
if (showtip) {
@ -883,7 +793,7 @@ global void GameMainLoop(void)
}
//
// Game over
// Game over
//
if (FastForwardCycle > GameCycle) {
VideoSyncSpeed = RealVideoSyncSpeed;

View file

@ -51,21 +51,21 @@
-- Variables
----------------------------------------------------------------------------*/
global char RightButtonAttacks; /// right button 0 move, 1 attack
global char FancyBuildings; /// Mirror buildings 1 yes, 0 now.
global char RightButtonAttacks; /// right button 0 move, 1 attack
global char FancyBuildings; /// Mirror buildings 1 yes, 0 now.
/// keyboard scroll speed
/// keyboard scroll speed
global int SpeedKeyScroll = KEY_SCROLL_SPEED;
/// mouse scroll speed
/// mouse scroll speed
global int SpeedMouseScroll = MOUSE_SCROLL_SPEED;
/**
** The user interface configuration
** The user interface configuration
*/
global UI TheUI;
/**
** The available user interfaces.
** The available user interfaces.
*/
global UI** UI_Table;
@ -108,13 +108,13 @@ local void CleanUIGraphics(UI* ui)
}
/**
** Initialize the user interface.
** Initialize the user interface.
**
** The function looks through ::UI_Table, to find a matching user
** interface. It uses the race_name and the current video window sizes to
** find it.
** The function looks through ::UI_Table, to find a matching user
** interface. It uses the race_name and the current video window sizes to
** find it.
**
** @param race_name The race identifier, to select the interface.
** @param race_name The race identifier, to select the interface.
*/
global void InitUserInterface(const char* race_name)
{
@ -161,7 +161,7 @@ global void InitUserInterface(const char* race_name)
TheUI.Offset480Y = (VideoHeight - 480) / 2;
//
// Calculations
// Calculations
//
if (TheUI.MapArea.EndX > TheMap.Width * TileSizeX - 1) {
TheUI.MapArea.EndX = TheMap.Width * TileSizeX - 1;
@ -191,11 +191,11 @@ global void InitUserInterface(const char* race_name)
}
/**
** Load the user interface graphics.
** Load the user interface graphics.
**
** @todo If sub images of the same graphic are used, they are loaded
** multiple into memory. Use the IconFile code and perhaps build
** a new layer, which supports image sharing.
** @todo If sub images of the same graphic are used, they are loaded
** multiple into memory. Use the IconFile code and perhaps build
** a new layer, which supports image sharing.
*/
global void LoadUserInterface(void)
{
@ -409,7 +409,7 @@ global void CleanUI(UI* ui)
}
/**
** Clean up the user interface module.
** Clean up the user interface module.
*/
global void CleanUserInterface(void)
{
@ -419,7 +419,7 @@ global void CleanUserInterface(void)
CleanUIGraphics(&TheUI);
//
// Free the available user interfaces.
// Free the available user interfaces.
//
if (UI_Table) {
for (i = 0; UI_Table[i]; ++i) {
@ -429,7 +429,7 @@ global void CleanUserInterface(void)
UI_Table = NULL;
}
// Free Title screen.
// Free Title screen.
if (TitleScreens) {
for (i = 0; TitleScreens[i]; ++i) {
free(TitleScreens[i]->File);
@ -451,17 +451,17 @@ global void CleanUserInterface(void)
}
/**
** Takes coordinates of a pixel in stratagus's window and computes
** the map viewport which contains this pixel.
** Takes coordinates of a pixel in stratagus's window and computes
** the map viewport which contains this pixel.
**
** @param x x pixel coordinate with origin at UL corner of screen
** @param y y pixel coordinate with origin at UL corner of screen
** @param x x pixel coordinate with origin at UL corner of screen
** @param y y pixel coordinate with origin at UL corner of screen
**
** @return viewport pointer or NULL if this pixel is not inside
** any of the viewports.
** @return viewport pointer or NULL if this pixel is not inside
** any of the viewports.
**
** @note This functions only works with rectangular viewports, when
** we support shaped map window, this must be rewritten.
** @note This functions only works with rectangular viewports, when
** we support shaped map window, this must be rewritten.
*/
global Viewport* GetViewport(int x, int y)
{
@ -476,19 +476,19 @@ global Viewport* GetViewport(int x, int y)
}
/**
** Takes coordinates of a map tile and computes the number of the map
** viewport (if any) inside which the tile is displayed.
** Takes coordinates of a map tile and computes the number of the map
** viewport (if any) inside which the tile is displayed.
**
** @param tx x coordinate of the map tile
** @param ty y coordinate of the map tile
** @param tx x coordinate of the map tile
** @param ty y coordinate of the map tile
**
** @return viewport pointer (index into TheUI.Viewports) or NULL
** if this map tile is not displayed in any of
** the viewports.
** @return viewport pointer (index into TheUI.Viewports) or NULL
** if this map tile is not displayed in any of
** the viewports.
**
** @note If the tile (tx,ty) is currently displayed in more
** than one viewports (may well happen) this function
** returns the first one it finds.
** @note If the tile (tx,ty) is currently displayed in more
** than one viewports (may well happen) this function
** returns the first one it finds.
*/
global Viewport* MapTileGetViewport(int tx, int ty)
{
@ -504,61 +504,46 @@ global Viewport* MapTileGetViewport(int tx, int ty)
}
/**
** Takes an array of new Viewports which are supposed to have their
** pixel geometry (Viewport::[XY] and Viewport::End[XY]) already
** computed. Using this information as well as old viewport's
** parameters fills in new viewports' Viewport::Map* parameters.
** Then it replaces the old viewports with the new ones and finishes
** the set-up of the new mode.
** Takes an array of new Viewports which are supposed to have their
** pixel geometry (Viewport::[XY] and Viewport::End[XY]) already
** computed. Using this information as well as old viewport's
** parameters fills in new viewports' Viewport::Map* parameters.
** Then it replaces the old viewports with the new ones and finishes
** the set-up of the new mode.
**
** @param new_vps The array of the new viewports
** @param num_vps The number of elements in the new_vps[] array.
** @param new_vps The array of the new viewports
** @param num_vps The number of elements in the new_vps[] array.
*/
local void FinishViewportModeConfiguration(Viewport new_vps[], int num_vps)
{
int i;
// If the number of viewports increases we need to compute what to display
// in the newly created ones. We need to do this before we store new
// geometry information in the TheUI.Viewports field because we use the old
// geometry information for map origin computation.
if (TheUI.NumViewports < num_vps) {
for (i = 0; i < num_vps; ++i) {
const Viewport* vp;
// Compute location of the viewport using oldviewport
for (i = 0; i < num_vps; ++i) {
const Viewport* vp;
vp = GetViewport(new_vps[i].X, new_vps[i].Y);
if (vp) {
TheUI.Viewports[i].MapX = Viewport2MapX(vp, new_vps[i].X);
TheUI.Viewports[i].MapY = Viewport2MapY(vp, new_vps[i].Y);
} else {
TheUI.Viewports[i].MapX = 0;
TheUI.Viewports[i].MapY = 0;
}
new_vps[i].MapX = 0;
new_vps[i].MapY = 0;
vp = GetViewport(new_vps[i].X, new_vps[i].Y);
if (vp) {
new_vps[i].OffsetX = new_vps[i].X - vp->X + vp->MapX * TileSizeX + vp->OffsetX;
new_vps[i].OffsetY = new_vps[i].Y - vp->Y + vp->MapY * TileSizeY + vp->OffsetY;
} else {
new_vps[i].OffsetX = 0;
new_vps[i].OffsetY = 0;
}
}
// Affect the old viewport.
for (i = 0; i < num_vps; ++i) {
TheUI.Viewports[i].X = new_vps[i].X;
TheUI.Viewports[i].EndX = new_vps[i].EndX;
TheUI.Viewports[i].Y = new_vps[i].Y;
TheUI.Viewports[i].EndY = new_vps[i].EndY;
TheUI.Viewports[i].MapWidth =
(new_vps[i].EndX - new_vps[i].X + TileSizeX) / TileSizeX + 1;
TheUI.Viewports[i].MapHeight =
(new_vps[i].EndY - new_vps[i].Y + TileSizeY) / TileSizeY + 1;
Viewport* vp;
if (TheUI.Viewports[i].MapWidth + TheUI.Viewports[i].MapX >
TheMap.Width) {
TheUI.Viewports[i].MapX -=
(TheUI.Viewports[i].MapWidth + TheUI.Viewports[i].MapX) -
TheMap.Width;
}
if (TheUI.Viewports[i].MapHeight + TheUI.Viewports[i].MapY >
TheMap.Height) {
TheUI.Viewports[i].MapY -=
(TheUI.Viewports[i].MapHeight + TheUI.Viewports[i].MapY) -
TheMap.Height;
}
vp = TheUI.Viewports + i;
vp->X = new_vps[i].X;
vp->EndX = new_vps[i].EndX;
vp->Y = new_vps[i].Y;
vp->EndY = new_vps[i].EndY;
ViewportSetViewpoint(vp, new_vps[i].MapX, new_vps[i].MapY, new_vps[i].OffsetX, new_vps[i].OffsetY);
}
TheUI.NumViewports = num_vps;
@ -572,20 +557,20 @@ local void FinishViewportModeConfiguration(Viewport new_vps[], int num_vps)
}
/**
** Takes a viewport which is supposed to have its Viewport::[XY]
** correctly filled-in and computes Viewport::End[XY] attributes
** according to clipping information passed in other two arguments.
** Takes a viewport which is supposed to have its Viewport::[XY]
** correctly filled-in and computes Viewport::End[XY] attributes
** according to clipping information passed in other two arguments.
**
** @param vp The viewport.
** @param ClipX Maximum x-coordinate of the viewport's right side
** as dictated by current UI's geometry and ViewportMode.
** @param ClipY Maximum y-coordinate of the viewport's bottom side
** as dictated by current UI's geometry and ViewportMode.
** @param vp The viewport.
** @param ClipX Maximum x-coordinate of the viewport's right side
** as dictated by current UI's geometry and ViewportMode.
** @param ClipY Maximum y-coordinate of the viewport's bottom side
** as dictated by current UI's geometry and ViewportMode.
**
** @note It is supposed that values passed in Clip[XY] will
** never be greater than TheUI::MapArea::End[XY].
** However, they can be smaller according to the place
** the viewport vp takes in context of current ViewportMode.
** @note It is supposed that values passed in Clip[XY] will
** never be greater than TheUI::MapArea::End[XY].
** However, they can be smaller according to the place
** the viewport vp takes in context of current ViewportMode.
*/
local void ClipViewport(Viewport* vp, int ClipX, int ClipY)
{
@ -603,15 +588,17 @@ local void ClipViewport(Viewport* vp, int ClipX, int ClipY)
vp->EndY = ClipY;
}
DebugCheck(vp->EndX > TheUI.MapArea.EndX);
DebugCheck(vp->EndY > TheUI.MapArea.EndY);
}
/**
** Compute viewport parameters for single viewport mode.
** Compute viewport parameters for single viewport mode.
**
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
*/
local void SetViewportModeSingle(void)
{
@ -627,14 +614,14 @@ local void SetViewportModeSingle(void)
}
/**
** Compute viewport parameters for horizontally split viewport mode.
** This mode splits the TheUI::MapArea with a horizontal line to
** 2 (approximately) equal parts.
** Compute viewport parameters for horizontally split viewport mode.
** This mode splits the TheUI::MapArea with a horizontal line to
** 2 (approximately) equal parts.
**
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
*/
local void SetViewportModeSplitHoriz(void)
{
@ -655,15 +642,15 @@ local void SetViewportModeSplitHoriz(void)
}
/**
** Compute viewport parameters for horizontal 3-way split viewport mode.
** This mode splits the TheUI::MapArea with a horizontal line to
** 2 (approximately) equal parts, then splits the bottom part vertically
** to another 2 parts.
** Compute viewport parameters for horizontal 3-way split viewport mode.
** This mode splits the TheUI::MapArea with a horizontal line to
** 2 (approximately) equal parts, then splits the bottom part vertically
** to another 2 parts.
**
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
*/
local void SetViewportModeSplitHoriz3(void)
{
@ -690,14 +677,14 @@ local void SetViewportModeSplitHoriz3(void)
}
/**
** Compute viewport parameters for vertically split viewport mode.
** This mode splits the TheUI::MapArea with a vertical line to
** 2 (approximately) equal parts.
** Compute viewport parameters for vertically split viewport mode.
** This mode splits the TheUI::MapArea with a vertical line to
** 2 (approximately) equal parts.
**
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
*/
local void SetViewportModeSplitVert(void)
{
@ -719,14 +706,14 @@ local void SetViewportModeSplitVert(void)
}
/**
** Compute viewport parameters for 4-way split viewport mode.
** This mode splits the TheUI::MapArea vertically *and* horizontally
** to 4 (approximately) equal parts.
** Compute viewport parameters for 4-way split viewport mode.
** This mode splits the TheUI::MapArea vertically *and* horizontally
** to 4 (approximately) equal parts.
**
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
** The parameters include viewport's width and height expressed
** in pixels, its position with respect to Stratagus's window
** origin, and the corresponding map parameters expressed in map
** tiles with origin at map origin (map tile (0,0)).
*/
local void SetViewportModeQuad(void)
{
@ -760,9 +747,9 @@ local void SetViewportModeQuad(void)
}
/**
** Sets up (calls geometry setup routines for) a new viewport mode.
** Sets up (calls geometry setup routines for) a new viewport mode.
**
** @param new_mode New mode's number.
** @param new_mode New mode's number.
*/
global void SetViewportMode(ViewportMode new_mode)
{
@ -789,12 +776,12 @@ global void SetViewportMode(ViewportMode new_mode)
}
/**
** Cycles through predefined viewport modes (geometry configurations)
** in order defined by the ViewportMode enumerated type.
** Cycles through predefined viewport modes (geometry configurations)
** in order defined by the ViewportMode enumerated type.
**
** @param step The size of step used for cycling. Values that
** make sense are mostly 1 (next viewport mode) and
* -1 (previous viewport mode).
** @param step The size of step used for cycling. Values that
** make sense are mostly 1 (next viewport mode) and
** -1 (previous viewport mode).
*/
global void CycleViewportMode(int step)
{