mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added missing #includes Added LUA scripting and console Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain Fixed signedness of many grid variables used in GetMouseMapPos calls Fixed enemy weapon choosing: Sometimes a mortar is chosen but later rejected, but the grenade class was not reset. Caused assertion failure Added checks so enemies don't try to chuck RPG grenades with their hands Now possible to shoot a someone in the head if he's in water Fixed InitSightArrays to also clear soldier interrupt duel points. This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called. Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have Removed early setting of muzzle flash. This would allow enemies to get an interrupt before you even fired. Fixed item dropping by AI. If AI tried to drop something while standing it would cause deadlock Change to greatly speed up closing the sector inventory window in an unloaded sector Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting Check builddefines.h for the conditional flags. Of greatest interest might be LUA_CONSOLE. This will cause the game to bring up a command console when run. However this console is severely lacking in many areas. If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated. The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus. LUA scripting is very limited, basically just proof of concept. There is one global variable, the Soldiers array. An array index gives you the soldier in that slot in the currently loaded sector. The soldier has a few things that can be accessed: name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
7550 lines
207 KiB
C++
7550 lines
207 KiB
C++
#include "builddefines.h"
|
|
|
|
#ifdef PRECOMPILEDHEADERS
|
|
#include "TileEngine All.h"
|
|
#else
|
|
#include "math.h"
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
|
|
#include "worlddef.h"
|
|
#include "renderworld.h"
|
|
#include "vsurface.h"
|
|
#include "input.h"
|
|
#include "sysutil.h"
|
|
#include "wchar.h"
|
|
#include "video.h"
|
|
#include "vobject_blitters.h"
|
|
#include "debug.h"
|
|
#include "wcheck.h"
|
|
#include "worldman.h"
|
|
#include "jascreens.h"
|
|
#include "edit_sys.h"
|
|
#include "Isometric Utils.h"
|
|
#include "line.h"
|
|
#include "Animation Control.h"
|
|
#include "Animation Data.h"
|
|
#include "Timer Control.h"
|
|
#include "Radar Screen.h"
|
|
#include "Render Dirty.h"
|
|
#include "Font Control.h"
|
|
#include "Sys Globals.h"
|
|
#include "Render Dirty.h"
|
|
#include "lighting.h"
|
|
#include "Overhead types.h"
|
|
#include "Overhead.h"
|
|
#include "weapons.h"
|
|
#include "ai.h"
|
|
#include "vobject.h"
|
|
#include "render fun.h"
|
|
#include "los.h"
|
|
#include "interactive tiles.h"
|
|
#include "interface cursors.h"
|
|
#include "rotting corpses.h"
|
|
#include "tile cache.h"
|
|
#include "tile animation.h"
|
|
#include "English.h"
|
|
#include "world items.h"
|
|
#include "GameSettings.h"
|
|
#include "interface control.h"
|
|
#include "Sound Control.h"
|
|
#endif
|
|
|
|
///////////////////////////
|
|
// C file include here
|
|
#include "Render Z.cpp"
|
|
///////////////////////////
|
|
|
|
extern CHAR8 gDebugStr[128];
|
|
extern BOOLEAN fLandLayerDirty = TRUE;
|
|
|
|
extern INT16 gsVIEWPORT_START_X;
|
|
extern INT16 gsVIEWPORT_START_Y;
|
|
extern INT16 gsVIEWPORT_END_Y;
|
|
extern INT16 gsVIEWPORT_WINDOW_END_Y;
|
|
extern INT16 gsVIEWPORT_WINDOW_START_Y;
|
|
extern INT16 gsVIEWPORT_END_X;
|
|
|
|
UINT16 *gpZBuffer = NULL;
|
|
BOOLEAN gfTagAnimatedTiles = TRUE;
|
|
|
|
INT16 gsCurrentGlowFrame = 0;
|
|
INT16 gsCurrentItemGlowFrame = 0;
|
|
|
|
extern BOOLEAN gfUIShowExitEast;
|
|
extern BOOLEAN gfUIShowExitWest;
|
|
extern BOOLEAN gfUIShowExitNorth;
|
|
extern BOOLEAN gfUIShowExitSouth;
|
|
extern BOOLEAN gfTopMessageDirty;
|
|
|
|
// VIEWPORT OFFSET VALUES
|
|
// NOTE:
|
|
// THESE VALUES MUST BE MULTIPLES OF TILE SIZES!
|
|
#define VIEWPORT_XOFFSET_S WORLD_TILE_X*1
|
|
#define VIEWPORT_YOFFSET_S WORLD_TILE_Y*2
|
|
#define LARGER_VIEWPORT_XOFFSET_S ( VIEWPORT_XOFFSET_S * 3 )
|
|
#define LARGER_VIEWPORT_YOFFSET_S ( VIEWPORT_YOFFSET_S * 5 )
|
|
|
|
#define TILES_TYPE_BITMASK 0x00040000
|
|
#define TILES_TYPE_MASK 0x07ffffff
|
|
#define TILES_DIRTY 0x80000000
|
|
#define TILES_DYNAMIC 0x40000000
|
|
#define TILES_NOZWRITE 0x20000000
|
|
#define TILES_MARKED 0x10000000
|
|
#define TILES_NOZ 0x04000000
|
|
#define TILES_DOALL 0x02000000
|
|
#define TILES_OBSCURED 0x01000000
|
|
|
|
//#define TILES_MERC 0x00000400
|
|
//#define TILES_Z_BLITTER 0x00000200
|
|
//#define TILES_Z_WRITE 0x00000100
|
|
//#define TILES_SHADOW 0x00000080
|
|
//#define TILES_BACKWARDS 0x00000040
|
|
|
|
#define MAX_RENDERED_ITEMS 3
|
|
|
|
// RENDERER FLAGS FOR DIFFERENT RENDER LEVELS
|
|
typedef enum
|
|
{
|
|
RENDER_STATIC_LAND, RENDER_STATIC_OBJECTS,
|
|
RENDER_STATIC_SHADOWS, RENDER_STATIC_STRUCTS,
|
|
RENDER_STATIC_ROOF, RENDER_STATIC_ONROOF,
|
|
RENDER_STATIC_TOPMOST, RENDER_DYNAMIC_LAND,
|
|
RENDER_DYNAMIC_OBJECTS, RENDER_DYNAMIC_SHADOWS,
|
|
RENDER_DYNAMIC_STRUCT_MERCS, RENDER_DYNAMIC_MERCS,
|
|
RENDER_DYNAMIC_STRUCTS, RENDER_DYNAMIC_ROOF,
|
|
RENDER_DYNAMIC_HIGHMERCS, RENDER_DYNAMIC_ONROOF,
|
|
RENDER_DYNAMIC_TOPMOST, NUM_RENDER_FX_TYPES
|
|
};
|
|
|
|
#define SCROLL_INTERTIA_STEP1 3//6
|
|
#define SCROLL_INTERTIA_STEP2 4//8
|
|
|
|
//#define SHORT_ROUND( x ) ( (INT16)( ( x * 1000 ) / 1000 ) )
|
|
#define SHORT_ROUND( x ) ( x )
|
|
|
|
#define NUM_ITEM_CYCLE_COLORS 60
|
|
|
|
UINT16 us16BPPItemCycleWhiteColors[ NUM_ITEM_CYCLE_COLORS ];
|
|
UINT16 us16BPPItemCycleRedColors[ NUM_ITEM_CYCLE_COLORS ];
|
|
UINT16 us16BPPItemCycleYellowColors[ NUM_ITEM_CYCLE_COLORS ];
|
|
|
|
INT16 gsLobOutline;
|
|
INT16 gsThrowOutline;
|
|
INT16 gsGiveOutline;
|
|
INT16 gusNormalItemOutlineColor;
|
|
INT16 gusYellowItemOutlineColor;
|
|
INT16 gsRenderHeight = 0;
|
|
BOOLEAN gfRenderFullThisFrame = 0;
|
|
|
|
INT16 gCenterWorldX;
|
|
|
|
//UINT8 gubIntTileCheckFlags = INTILE_CHECK_FULL;
|
|
UINT8 gubIntTileCheckFlags = INTILE_CHECK_SELECTIVE;
|
|
|
|
UINT8 ubRGBItemCycleWhiteColors[] =
|
|
{
|
|
25, 25, 25,
|
|
50, 50, 50,
|
|
75, 75, 75,
|
|
100, 100, 100,
|
|
125, 125, 125,
|
|
150, 150, 150,
|
|
175, 175, 175,
|
|
200, 200, 200,
|
|
225, 225, 225,
|
|
250, 250, 250,
|
|
|
|
250, 250, 250,
|
|
225, 225, 225,
|
|
200, 200, 200,
|
|
175, 175, 175,
|
|
150, 150, 150,
|
|
125, 125, 125,
|
|
100, 100, 100,
|
|
75, 75, 75,
|
|
50, 50, 50,
|
|
25, 25, 25,
|
|
|
|
25, 25, 25,
|
|
50, 50, 50,
|
|
75, 75, 75,
|
|
100, 100, 100,
|
|
125, 125, 125,
|
|
150, 150, 150,
|
|
175, 175, 175,
|
|
200, 200, 200,
|
|
225, 225, 225,
|
|
250, 250, 250,
|
|
|
|
250, 250, 250,
|
|
225, 225, 225,
|
|
200, 200, 200,
|
|
175, 175, 175,
|
|
150, 150, 150,
|
|
125, 125, 125,
|
|
100, 100, 100,
|
|
75, 75, 75,
|
|
50, 50, 50,
|
|
25, 25, 25,
|
|
|
|
25, 25, 25,
|
|
50, 50, 50,
|
|
75, 75, 75,
|
|
100, 100, 100,
|
|
125, 125, 125,
|
|
150, 150, 150,
|
|
175, 175, 175,
|
|
200, 200, 200,
|
|
225, 225, 225,
|
|
250, 250, 250,
|
|
|
|
250, 250, 250,
|
|
225, 225, 225,
|
|
200, 200, 200,
|
|
175, 175, 175,
|
|
150, 150, 150,
|
|
125, 125, 125,
|
|
100, 100, 100,
|
|
75, 75, 75,
|
|
50, 50, 50,
|
|
25, 25, 25
|
|
};
|
|
|
|
UINT8 ubRGBItemCycleRedColors[] =
|
|
{
|
|
25, 0, 0,
|
|
50, 0, 0,
|
|
75, 0, 0,
|
|
100, 0, 0,
|
|
125, 0, 0,
|
|
150, 0, 0,
|
|
175, 0, 0,
|
|
200, 0, 0,
|
|
225, 0, 0,
|
|
250, 0, 0,
|
|
|
|
250, 0, 0,
|
|
225, 0, 0,
|
|
200, 0, 0,
|
|
175, 0, 0,
|
|
150, 0, 0,
|
|
125, 0, 0,
|
|
100, 0, 0,
|
|
75, 0, 0,
|
|
50, 0, 0,
|
|
25, 0, 0,
|
|
|
|
25, 0, 0,
|
|
50, 0, 0,
|
|
75, 0, 0,
|
|
100, 0, 0,
|
|
125, 0, 0,
|
|
150, 0, 0,
|
|
175, 0, 0,
|
|
200, 0, 0,
|
|
225, 0, 0,
|
|
250, 0, 0,
|
|
|
|
250, 0, 0,
|
|
225, 0, 0,
|
|
200, 0, 0,
|
|
175, 0, 0,
|
|
150, 0, 0,
|
|
125, 0, 0,
|
|
100, 0, 0,
|
|
75, 0, 0,
|
|
50, 0, 0,
|
|
25, 0, 0,
|
|
|
|
25, 0, 0,
|
|
50, 0, 0,
|
|
75, 0, 0,
|
|
100, 0, 0,
|
|
125, 0, 0,
|
|
150, 0, 0,
|
|
175, 0, 0,
|
|
200, 0, 0,
|
|
225, 0, 0,
|
|
250, 0, 0,
|
|
|
|
250, 0, 0,
|
|
225, 0, 0,
|
|
200, 0, 0,
|
|
175, 0, 0,
|
|
150, 0, 0,
|
|
125, 0, 0,
|
|
100, 0, 0,
|
|
75, 0, 0,
|
|
50, 0, 0,
|
|
25, 0, 0,
|
|
};
|
|
|
|
UINT8 ubRGBItemCycleYellowColors[] =
|
|
{
|
|
25, 25, 0,
|
|
50, 50, 0,
|
|
75, 75, 0,
|
|
100, 100, 0,
|
|
125, 125, 0,
|
|
150, 150, 0,
|
|
175, 175, 0,
|
|
200, 200, 0,
|
|
225, 225, 0,
|
|
250, 250, 0,
|
|
|
|
250, 250, 0,
|
|
225, 225, 0,
|
|
200, 200, 0,
|
|
175, 175, 0,
|
|
150, 150, 0,
|
|
125, 125, 0,
|
|
100, 100, 0,
|
|
75, 75, 0,
|
|
50, 50, 0,
|
|
25, 25, 0,
|
|
|
|
25, 25, 0,
|
|
50, 50, 0,
|
|
75, 75, 0,
|
|
100, 100, 0,
|
|
125, 125, 0,
|
|
150, 150, 0,
|
|
175, 175, 0,
|
|
200, 200, 0,
|
|
225, 225, 0,
|
|
250, 250, 0,
|
|
|
|
250, 250, 0,
|
|
225, 225, 0,
|
|
200, 200, 0,
|
|
175, 175, 0,
|
|
150, 150, 0,
|
|
125, 125, 0,
|
|
100, 100, 0,
|
|
75, 75, 0,
|
|
50, 50, 0,
|
|
25, 25, 0,
|
|
|
|
25, 25, 0,
|
|
50, 50, 0,
|
|
75, 75, 0,
|
|
100, 100, 0,
|
|
125, 125, 0,
|
|
150, 150, 0,
|
|
175, 175, 0,
|
|
200, 200, 0,
|
|
225, 225, 0,
|
|
250, 250, 0,
|
|
|
|
250, 250, 0,
|
|
225, 225, 0,
|
|
200, 200, 0,
|
|
175, 175, 0,
|
|
150, 150, 0,
|
|
125, 125, 0,
|
|
100, 100, 0,
|
|
75, 75, 0,
|
|
50, 50, 0,
|
|
25, 25, 0,
|
|
};
|
|
|
|
#define NUMSPEEDS 5
|
|
|
|
UINT8 gubNewScrollXSpeeds[2][ NUMSPEEDS ] =
|
|
{
|
|
40, 80, 100, 180, 200, // Non-video mode scroll
|
|
20, 40, 80, 80, 80 // Video mode scroll
|
|
};
|
|
|
|
UINT8 gubNewScrollYSpeeds[2][ NUMSPEEDS ] =
|
|
{
|
|
40, 80, 100, 180, 200, // Non-video mode scroll
|
|
10, 20, 60, 80, 80 // Video mode scroll
|
|
};
|
|
|
|
// These speeds are only an indication of how long to do each subtile step until moving on to another
|
|
UINT8 gubNewScrollIDSpeeds[ ] = { 10, 10, 20, 20, 20 };
|
|
UINT8 gubScrollSpeedStartID = 2;
|
|
UINT8 gubScrollSpeedEndID = 4;
|
|
UINT8 gubCurScrollSpeedID = 1;
|
|
BOOLEAN gfDoVideoScroll = TRUE;
|
|
BOOLEAN gfDoSubtileScroll = FALSE;
|
|
BOOLEAN gfScrollPending = FALSE;
|
|
UINT32 uiLayerUsedFlags = 0xffffffff;
|
|
UINT32 uiAdditiveLayerUsedFlags = 0xffffffff;
|
|
|
|
// Array of shade values to use.....
|
|
#define NUM_GLOW_FRAMES 30
|
|
|
|
#if 0
|
|
INT16 gsGlowFrames[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
|
9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
|
|
};
|
|
#endif
|
|
|
|
INT16 gsGlowFrames[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
2, 4, 6, 8, 9, 8, 6, 4, 2, 0,
|
|
};
|
|
|
|
// This has to be the same # of frames as NUM_GLOW_FRAMES
|
|
INT16 gsFastGlowFrames[] =
|
|
{
|
|
0, 0, 6, 7, 8, 9, 8, 7, 6, 5,
|
|
0, 0, 6, 7, 8, 9, 8, 7, 6, 5,
|
|
0, 0, 6, 7, 8, 9, 8, 7, 6, 5,
|
|
};
|
|
|
|
// The glow frame pointer can be adjusted to use a faster/ slower glow
|
|
INT16 *gpGlowFramePointer = gsGlowFrames;
|
|
|
|
UINT32 gScrollDirectionFlags[ NUM_WORLD_DIRECTIONS ] =
|
|
{
|
|
SCROLL_UP | SCROLL_RIGHT,
|
|
SCROLL_RIGHT,
|
|
SCROLL_DOWN | SCROLL_RIGHT,
|
|
SCROLL_DOWN,
|
|
SCROLL_DOWN | SCROLL_LEFT,
|
|
SCROLL_LEFT,
|
|
SCROLL_UP | SCROLL_LEFT,
|
|
SCROLL_UP,
|
|
};
|
|
|
|
INT16 SCROLL_X_STEP = ( WORLD_TILE_X );
|
|
INT16 SCROLL_Y_STEP = ( WORLD_TILE_Y * 2);
|
|
|
|
/*
|
|
* ViewPort starting values
|
|
* What is viewport?
|
|
* So viewport are coords of map screen (tactical screen)
|
|
* gsViewport_xxx this variables are related with mouse regions, current rendering region ...
|
|
* this variables ware unnecessary with this GUI becouse they can be calculated from INTERFACE coords
|
|
* but i think that they can be realy usefull while we will change GUI for more customisable
|
|
* any questions? joker
|
|
*/
|
|
/*
|
|
INT16 gsVIEWPORT_START_X = 0;
|
|
INT16 gsVIEWPORT_START_Y = 0;
|
|
INT16 gsVIEWPORT_WINDOW_START_Y = 0;
|
|
INT16 gsVIEWPORT_WINDOW_END_Y = INTERFACE_START_Y;//do zmiany
|
|
INT16 gsVIEWPORT_END_X = SCREEN_WIDTH;
|
|
INT16 gsVIEWPORT_END_Y = INTERFACE_START_Y;
|
|
|
|
i changed for dynamic initialization joker
|
|
*/
|
|
// still need the global object container defined atleast once outside a header (jonathanl)
|
|
INT16 gsVIEWPORT_START_X = 0;
|
|
INT16 gsVIEWPORT_START_Y = 0;
|
|
INT16 gsVIEWPORT_WINDOW_START_Y = 0;
|
|
INT16 gsVIEWPORT_WINDOW_END_Y = INTERFACE_START_Y;
|
|
INT16 gsVIEWPORT_END_X = SCREEN_WIDTH;
|
|
INT16 gsVIEWPORT_END_Y = INTERFACE_START_Y;
|
|
|
|
INT16 gsTopLeftWorldX, gsTopLeftWorldY;
|
|
INT16 gsTopRightWorldX, gsTopRightWorldY;
|
|
INT16 gsBottomLeftWorldX, gsBottomLeftWorldY;
|
|
INT16 gsBottomRightWorldX, gsBottomRightWorldY;
|
|
BOOLEAN gfIgnoreScrolling = FALSE;
|
|
|
|
// WANNE: If we are talking?
|
|
// This check is used, to prevent scrolling in small maps (e.g: Rebel Basement) in higher resolution (1024x768) [2007-05-14]
|
|
BOOLEAN gfDialogControl = FALSE;
|
|
|
|
BOOLEAN gfIgnoreScrollDueToCenterAdjust = FALSE;
|
|
|
|
// GLOBAL SCROLLING PARAMS
|
|
INT16 gTopLeftWorldLimitX, gTopLeftWorldLimitY;
|
|
INT16 gTopRightWorldLimitX, gTopRightWorldLimitY;
|
|
INT16 gBottomLeftWorldLimitX, gBottomLeftWorldLimitY;
|
|
INT16 gBottomRightWorldLimitX, gBottomRightWorldLimitY;
|
|
INT16 Slide, gCenterWorldY;
|
|
INT16 gsTLX, gsTLY, gsTRX, gsTRY;
|
|
INT16 gsBLX, gsBLY, gsBRX, gsBRY;
|
|
INT16 gsCX, gsCY;
|
|
DOUBLE gdScaleX, gdScaleY;
|
|
|
|
#define FASTMAPROWCOLTOPOS( r, c ) ( (r) * WORLD_COLS + (c) )
|
|
|
|
BOOLEAN gfScrollInertia = FALSE;
|
|
|
|
// GLOBALS FOR CALCULATING STARTING PARAMETERS
|
|
INT16 gsStartPointX_W, gsStartPointY_W;
|
|
INT16 gsStartPointX_S, gsStartPointY_S;
|
|
INT16 gsStartPointX_M, gsStartPointY_M;
|
|
INT16 gsEndXS, gsEndYS;
|
|
// LARGER OFFSET VERSION FOR GIVEN LAYERS
|
|
INT16 gsLStartPointX_W, gsLStartPointY_W;
|
|
INT16 gsLStartPointX_S, gsLStartPointY_S;
|
|
INT16 gsLStartPointX_M, gsLStartPointY_M;
|
|
INT16 gsLEndXS, gsLEndYS;
|
|
|
|
BOOLEAN gfRenderScroll = FALSE;
|
|
BOOLEAN gfScrollStart = FALSE;
|
|
INT16 gsScrollXIncrement;
|
|
INT16 gsScrollYIncrement;
|
|
INT32 guiScrollDirection;
|
|
|
|
// Rendering flags (full, partial, etc.)
|
|
UINT32 gRenderFlags=0;
|
|
|
|
/* You know it was static and now it will be dynamic :P
|
|
* any questions? joker
|
|
*/
|
|
SGPRect gClippingRect;// = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - INTERFACE_HEIGHT};
|
|
SGPRect gOldClipRect = { 0, 0, 1024, 768 }; // 0verhaul: This MUST mirror the gDirtyClipRect init, otherwise funkiness with video overlays will happen
|
|
INT16 gsRenderCenterX;
|
|
INT16 gsRenderCenterY;
|
|
INT16 gsRenderWorldOffsetX = 0; //lal was -1 : bugfix for merc screen position in tactical on high resolution
|
|
INT16 gsRenderWorldOffsetY = 10; //lal was -1
|
|
SGPRect gSelectRegion;
|
|
UINT32 fSelectMode = NO_SELECT;
|
|
SGPPoint gSelectAnchor;
|
|
|
|
typedef struct
|
|
{
|
|
BOOLEAN fDynamic;
|
|
BOOLEAN fZWrite;
|
|
BOOLEAN fZBlitter;
|
|
BOOLEAN fShadowBlitter;
|
|
BOOLEAN fLinkedListDirection;
|
|
BOOLEAN fMerc;
|
|
BOOLEAN fCheckForRedundency;
|
|
BOOLEAN fMultiZBlitter;
|
|
BOOLEAN fConvertTo16;
|
|
BOOLEAN fObscured;
|
|
} RenderFXType;
|
|
|
|
RenderFXType RenderFX[] =
|
|
{
|
|
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, // STATIC LAND
|
|
FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, // STATIC OBJECTS
|
|
FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // STATIC SHADOWS
|
|
FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, // STATIC STRUCTS
|
|
FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // STATIC ROOF
|
|
FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, // STATIC ONROOF
|
|
FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // STATIC TOPMOST
|
|
TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, // DYNAMIC LAND
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, // DYNAMIC OBJECT
|
|
TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC SHADOW
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC STRUCT MERCS
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC MERCS
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC STRUCT
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC ROOF
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC HIGHMERCS
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, // DYNAMIC ONROOF
|
|
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE // DYNAMIC TOPMOST
|
|
};
|
|
|
|
UINT8 RenderFXStartIndex[] =
|
|
{
|
|
LAND_START_INDEX, // STATIC LAND
|
|
OBJECT_START_INDEX, // STATIC OBJECTS
|
|
SHADOW_START_INDEX, // STATIC SHADOWS
|
|
STRUCT_START_INDEX, // STATIC STRUCTS
|
|
ROOF_START_INDEX, // STATIC ROOF
|
|
ONROOF_START_INDEX, // STATIC ONROOF
|
|
TOPMOST_START_INDEX, // STATIC TOPMOST
|
|
LAND_START_INDEX, // DYNAMIC LAND
|
|
OBJECT_START_INDEX, // DYNAMIC OBJECT
|
|
SHADOW_START_INDEX, // DYNAMIC SHADOW
|
|
MERC_START_INDEX, // DYNAMIC STRUCT MERCS
|
|
MERC_START_INDEX, // DYNAMIC MERCS
|
|
STRUCT_START_INDEX, // DYNAMIC STRUCT
|
|
ROOF_START_INDEX, // DYNAMIC ROOF
|
|
MERC_START_INDEX, // DYNAMIC HIGHMERCS
|
|
ONROOF_START_INDEX, // DYNAMIC ONROOF
|
|
TOPMOST_START_INDEX, // DYNAMIC TOPMOST
|
|
};
|
|
|
|
|
|
//INT16 gsCoordArray[ 500 ][ 500 ][ 4 ];
|
|
//INT16 gsCoordArrayX;
|
|
//INT16 gsCoordArrayY;
|
|
//void SetRenderGlobals( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
//void TempRenderTiles(UINT32 uiFlags, INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
//void TempRenderTiles(UINT32 uiFlags, INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS, UINT8 ubNumLevels, UINT32 *puiLevels );
|
|
|
|
void ExamineZBufferForHiddenTiles( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
|
|
//void ReRenderWorld(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom);
|
|
void ClearMarkedTiles(void);
|
|
void CorrectRenderCenter( INT16 sRenderX, INT16 sRenderY, INT16 *pSNewX, INT16 *pSNewY );
|
|
void ScrollBackground(UINT32 uiDirection, INT16 sScrollXIncrement, INT16 sScrollYIncrement );
|
|
void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom );
|
|
void ResetRenderParameters( );
|
|
|
|
|
|
void RenderRoomInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
|
|
|
|
#ifdef _DEBUG
|
|
extern UINT8 gubFOVDebugInfoInfo[ WORLD_MAX ];
|
|
extern UINT8 gubGridNoMarkers[ WORLD_MAX ];
|
|
extern UINT8 gubGridNoValue;
|
|
extern BOOLEAN gfDisplayCoverValues;
|
|
extern BOOLEAN gfDisplayGridNoVisibleValues = 0;
|
|
extern INT16 gsCoverValue[ WORLD_MAX ];
|
|
extern INT16 gsBestCover;
|
|
void RenderFOVDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
void RenderCoverDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
void RenderGridNoVisibleDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
#endif
|
|
|
|
void DeleteFromWorld( UINT16 usTileIndex, UINT32 uiRenderTiles, UINT16 usIndex );
|
|
|
|
void RenderHighlight( INT16 sMouseX_M, INT16 sMouseY_M, INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS );
|
|
BOOLEAN CheckRenderCenter( INT16 sNewCenterX, INT16 sNewCenterY );
|
|
|
|
BOOLEAN RevealWalls(INT16 sX, INT16 sY, INT16 sRadius)
|
|
{
|
|
LEVELNODE *pStruct;
|
|
INT16 sCountX, sCountY;
|
|
UINT32 uiTile;
|
|
BOOLEAN fRerender=FALSE;
|
|
TILE_ELEMENT *TileElem;
|
|
|
|
for(sCountY=sY-sRadius; sCountY < (sY+sRadius+2); sCountY++)
|
|
for(sCountX=sX-sRadius; sCountX < (sX+sRadius+2); sCountX++)
|
|
{
|
|
uiTile=FASTMAPROWCOLTOPOS(sCountY, sCountX);
|
|
pStruct=gpWorldLevelData[uiTile].pStructHead;
|
|
|
|
while(pStruct!=NULL)
|
|
{
|
|
TileElem = &(gTileDatabase[pStruct->usIndex]);
|
|
switch(TileElem->usWallOrientation)
|
|
{
|
|
case NO_ORIENTATION:
|
|
break;
|
|
|
|
case INSIDE_TOP_RIGHT:
|
|
case OUTSIDE_TOP_RIGHT:
|
|
if(sCountX >= sX)
|
|
{
|
|
pStruct->uiFlags|=LEVELNODE_REVEAL;
|
|
fRerender=TRUE;
|
|
}
|
|
break;
|
|
|
|
case INSIDE_TOP_LEFT:
|
|
case OUTSIDE_TOP_LEFT:
|
|
if(sCountY >= sY)
|
|
{
|
|
pStruct->uiFlags|=LEVELNODE_REVEAL;
|
|
fRerender=TRUE;
|
|
}
|
|
break;
|
|
}
|
|
pStruct=pStruct->pNext;
|
|
}
|
|
}
|
|
|
|
/*
|
|
if(fRerender)
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
*/
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOLEAN ConcealWalls(INT16 sX, INT16 sY, INT16 sRadius)
|
|
{
|
|
LEVELNODE *pStruct;
|
|
INT16 sCountX, sCountY;
|
|
UINT32 uiTile;
|
|
BOOLEAN fRerender=FALSE;
|
|
TILE_ELEMENT *TileElem;
|
|
|
|
|
|
for(sCountY=sY-sRadius; sCountY < (sY+sRadius+2); sCountY++)
|
|
for(sCountX=sX-sRadius; sCountX < (sX+sRadius+2); sCountX++)
|
|
{
|
|
uiTile=FASTMAPROWCOLTOPOS(sCountY, sCountX);
|
|
pStruct=gpWorldLevelData[uiTile].pStructHead;
|
|
|
|
while(pStruct!=NULL)
|
|
{
|
|
TileElem = &(gTileDatabase[pStruct->usIndex]);
|
|
switch(TileElem->usWallOrientation)
|
|
{
|
|
case NO_ORIENTATION:
|
|
break;
|
|
|
|
case INSIDE_TOP_RIGHT:
|
|
case OUTSIDE_TOP_RIGHT:
|
|
if(sCountX >= sX)
|
|
{
|
|
pStruct->uiFlags&=(~LEVELNODE_REVEAL);
|
|
fRerender=TRUE;
|
|
}
|
|
break;
|
|
|
|
case INSIDE_TOP_LEFT:
|
|
case OUTSIDE_TOP_LEFT:
|
|
if(sCountY >= sY)
|
|
{
|
|
pStruct->uiFlags&=(~LEVELNODE_REVEAL);
|
|
fRerender=TRUE;
|
|
}
|
|
break;
|
|
}
|
|
pStruct=pStruct->pNext;
|
|
}
|
|
}
|
|
|
|
/*
|
|
if(fRerender)
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
*/
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
void ConcealAllWalls(void)
|
|
{
|
|
LEVELNODE *pStruct;
|
|
UINT32 uiCount;
|
|
|
|
for(uiCount=0; uiCount < WORLD_MAX; uiCount++)
|
|
{
|
|
pStruct=gpWorldLevelData[uiCount].pStructHead;
|
|
while(pStruct!=NULL)
|
|
{
|
|
pStruct->uiFlags&=(~LEVELNODE_REVEAL);
|
|
pStruct=pStruct->pNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ResetLayerOptimizing(void)
|
|
{
|
|
uiLayerUsedFlags = 0xffffffff;
|
|
uiAdditiveLayerUsedFlags = 0;
|
|
}
|
|
|
|
void ResetSpecificLayerOptimizing( UINT32 uiRowFlag )
|
|
{
|
|
uiLayerUsedFlags |= uiRowFlag;
|
|
}
|
|
|
|
|
|
void SumAddiviveLayerOptimization( void )
|
|
{
|
|
uiLayerUsedFlags = uiAdditiveLayerUsedFlags;
|
|
}
|
|
|
|
void SetRenderFlags(UINT32 uiFlags)
|
|
{
|
|
gRenderFlags|=uiFlags;
|
|
}
|
|
|
|
void ClearRenderFlags(UINT32 uiFlags)
|
|
{
|
|
gRenderFlags&=(~uiFlags);
|
|
}
|
|
|
|
UINT32 GetRenderFlags(void)
|
|
{
|
|
return(gRenderFlags);
|
|
}
|
|
|
|
void RenderSetShadows(BOOLEAN fShadows)
|
|
{
|
|
if(fShadows)
|
|
{
|
|
gRenderFlags|=RENDER_FLAG_SHADOWS;
|
|
}
|
|
else
|
|
{
|
|
gRenderFlags&=(~RENDER_FLAG_SHADOWS);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RenderTiles(UINT32 uiFlags, INT32 iStartPointX_M, INT32 iStartPointY_M, INT32 iStartPointX_S, INT32 iStartPointY_S, INT32 iEndXS, INT32 iEndYS, UINT8 ubNumLevels, UINT32 *puiLevels, UINT16 *psLevelIDs )
|
|
{
|
|
|
|
//#if 0
|
|
|
|
LEVELNODE *pNode; //, *pLand, *pStruct; //*pObject, *pTopmost, *pMerc;
|
|
SOLDIERTYPE *pSoldier, *pSelSoldier;
|
|
HVOBJECT hVObject;
|
|
ETRLEObject *pTrav;
|
|
TILE_ELEMENT *TileElem=NULL;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf=NULL;
|
|
UINT16 usAnimSurface;
|
|
INT8 bXOddFlag = 0;
|
|
INT32 iAnchorPosX_M, iAnchorPosY_M;
|
|
INT32 iAnchorPosX_S, iAnchorPosY_S;
|
|
INT32 iTempPosX_M, iTempPosY_M;
|
|
INT32 iTempPosX_S, iTempPosY_S;
|
|
FLOAT dOffsetX, dOffsetY;
|
|
FLOAT dTempX_S, dTempY_S;
|
|
UINT32 uiTileIndex;
|
|
UINT16 usImageIndex, *pShadeTable, *pDirtyBackPtr;
|
|
UINT32 uiBrushWidth, uiBrushHeight, uiDirtyFlags;
|
|
INT16 sTileHeight, sXPos, sYPos, sZLevel;
|
|
INT16 sMouseX_M, sMouseY_M;
|
|
BOOLEAN fShadowBlitter=FALSE;
|
|
BOOLEAN fZBlitter=FALSE;
|
|
BOOLEAN fZWrite=FALSE;
|
|
BOOLEAN fLinkedListDirection=TRUE;
|
|
BOOLEAN fRenderTile=TRUE;
|
|
BOOLEAN fMerc=FALSE;
|
|
BOOLEAN fCheckForRedundency=FALSE;
|
|
UINT32 uiRowFlags;
|
|
BOOLEAN fDynamic=TRUE;
|
|
BOOLEAN fEndRenderRow = FALSE;
|
|
BOOLEAN fEndRenderCol = FALSE;
|
|
BOOLEAN fPixelate=FALSE;
|
|
BOOLEAN fMultiZBlitter = FALSE;
|
|
BOOLEAN fWallTile = FALSE;
|
|
BOOLEAN fMultiTransShadowZBlitter = FALSE;
|
|
INT16 sMultiTransShadowZBlitterIndex=-1;
|
|
BOOLEAN fTranslucencyType=FALSE;
|
|
INT16 sX, sY;
|
|
BOOLEAN fTileInvisible = FALSE;
|
|
BOOLEAN fConvertTo16=FALSE;
|
|
BOOLEAN fBlit16=FALSE;
|
|
UINT32 cnt;
|
|
static UINT8 ubLevelNodeStartIndex[ NUM_RENDER_FX_TYPES ];
|
|
BOOLEAN bItemOutline;
|
|
UINT16 usOutlineColor=0;
|
|
|
|
static INT32 iTileMapPos[ 500 ];
|
|
UINT32 uiMapPosIndex;
|
|
UINT8 bBlitClipVal;
|
|
INT8 bItemCount, bVisibleItemCount;
|
|
//UINT16 us16BPPIndex;
|
|
RenderFXType RenderingFX;
|
|
BOOLEAN fCheckForMouseDetections = FALSE;
|
|
static RenderFXType RenderFXList[ NUM_RENDER_FX_TYPES ];
|
|
BOOLEAN fSaveZ;
|
|
INT16 sWorldY;
|
|
INT16 sZOffsetX=-1;
|
|
INT16 sZOffsetY=-1;
|
|
BOOLEAN fIntensityBlitter;
|
|
INT16 gsForceSoldierZLevel;
|
|
ROTTING_CORPSE *pCorpse=NULL;
|
|
BOOLEAN fUseTileElem;
|
|
UINT32 uiLevelNodeFlags;
|
|
UINT32 uiTileElemFlags=0;
|
|
INT8 bGlowShadeOffset;
|
|
BOOLEAN fObscured;
|
|
BOOLEAN fObscuredBlitter;
|
|
INT16 sModifiedTileHeight;
|
|
BOOLEAN fDoRow;
|
|
INT16 **pShadeStart;
|
|
|
|
UINT32 uiSaveBufferPitchBYTES;
|
|
UINT8 *pSaveBuf;
|
|
ITEM_POOL *pItemPool = NULL;
|
|
BOOLEAN fHiddenTile = FALSE;
|
|
UINT32 uiAniTileFlags = 0;
|
|
INT16 sZStripIndex;
|
|
|
|
//Init some variables
|
|
usImageIndex = 0;
|
|
sZLevel = 0;
|
|
uiDirtyFlags = 0;
|
|
pShadeTable = NULL;
|
|
|
|
// Begin Render Loop
|
|
iAnchorPosX_M = iStartPointX_M;
|
|
iAnchorPosY_M = iStartPointY_M;
|
|
iAnchorPosX_S = iStartPointX_S;
|
|
iAnchorPosY_S = iStartPointY_S;
|
|
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
|
|
if ( uiFlags & TILES_DYNAMIC_CHECKFOR_INT_TILE )
|
|
{
|
|
if ( ShouldCheckForMouseDetections( ) )
|
|
{
|
|
BeginCurInteractiveTileCheck( gubIntTileCheckFlags );
|
|
fCheckForMouseDetections = TRUE;
|
|
|
|
// If we are in edit mode, don't do this...
|
|
if ( gfEditMode )
|
|
{
|
|
fCheckForMouseDetections = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//if((uiFlags&TILES_TYPE_MASK)==TILES_STATIC_LAND)
|
|
GetMouseXY( &sMouseX_M, &sMouseY_M );
|
|
|
|
pDirtyBackPtr=NULL;
|
|
|
|
if(gTacticalStatus.uiFlags&TRANSLUCENCY_TYPE)
|
|
fTranslucencyType=TRUE;
|
|
|
|
for ( cnt = 0; cnt < ubNumLevels; cnt++ )
|
|
{
|
|
ubLevelNodeStartIndex[ cnt ] = RenderFXStartIndex[ psLevelIDs[ cnt ] ];
|
|
RenderFXList[ cnt ] = RenderFX[ psLevelIDs[ cnt ] ];
|
|
}
|
|
|
|
do
|
|
{
|
|
|
|
iTempPosX_M = iAnchorPosX_M;
|
|
iTempPosY_M = iAnchorPosY_M;
|
|
iTempPosX_S = iAnchorPosX_S;
|
|
iTempPosY_S = iAnchorPosY_S;
|
|
|
|
uiMapPosIndex = 0;
|
|
|
|
// Build tile index list
|
|
do
|
|
{
|
|
iTileMapPos[ uiMapPosIndex ] = FASTMAPROWCOLTOPOS( iTempPosY_M, iTempPosX_M );
|
|
|
|
iTempPosX_S += 40;
|
|
iTempPosX_M ++;
|
|
iTempPosY_M --;
|
|
|
|
uiMapPosIndex++;
|
|
|
|
} while( iTempPosX_S < iEndXS );
|
|
|
|
|
|
|
|
for ( cnt = 0; cnt < ubNumLevels; cnt++ )
|
|
{
|
|
|
|
uiRowFlags = puiLevels[ cnt ];
|
|
fDoRow = TRUE;
|
|
|
|
if ( ( uiRowFlags & TILES_ALL_DYNAMICS ) && !( uiLayerUsedFlags & uiRowFlags ) && !( uiFlags & TILES_DYNAMIC_CHECKFOR_INT_TILE ) )
|
|
{
|
|
fDoRow = FALSE;
|
|
}
|
|
|
|
if ( fDoRow )
|
|
{
|
|
iTempPosX_M = iAnchorPosX_M;
|
|
iTempPosY_M = iAnchorPosY_M;
|
|
iTempPosX_S = iAnchorPosX_S;
|
|
iTempPosY_S = iAnchorPosY_S;
|
|
|
|
fEndRenderRow = FALSE;
|
|
uiMapPosIndex = 0;
|
|
|
|
|
|
if(bXOddFlag > 0)
|
|
iTempPosX_S += 20;
|
|
|
|
do
|
|
{
|
|
|
|
uiTileIndex = iTileMapPos[ uiMapPosIndex ];
|
|
uiMapPosIndex++;
|
|
|
|
//if ( 0 )
|
|
if ( uiTileIndex < GRIDSIZE )
|
|
{
|
|
// OK, we're sreaching through this loop anyway, might as well check for mouse position
|
|
// over objects...
|
|
// Experimental!
|
|
if ( uiFlags & TILES_DYNAMIC_CHECKFOR_INT_TILE )
|
|
{
|
|
if ( fCheckForMouseDetections && gpWorldLevelData[uiTileIndex].pStructHead != NULL )
|
|
{
|
|
LogMouseOverInteractiveTile( (INT16)uiTileIndex );
|
|
}
|
|
}
|
|
|
|
if((uiFlags&TILES_MARKED) && !(gpWorldLevelData[uiTileIndex].uiFlags&MAPELEMENT_REDRAW))
|
|
{
|
|
pNode=NULL;
|
|
}
|
|
else
|
|
{
|
|
//pNode = gpWorldLevelData[ uiTileIndex ].pLevelNodes[ RenderFXStartIndex[ psLevelIDs[ cnt ] ] ];
|
|
//pNode = gpWorldLevelData[ uiTileIndex ].pLevelNodes[ 0 ];
|
|
//pNode=NULL;
|
|
pNode = gpWorldLevelData[ uiTileIndex ].pLevelNodes[ ubLevelNodeStartIndex[ cnt ] ];
|
|
}
|
|
|
|
bItemCount = 0;
|
|
bVisibleItemCount = 0;
|
|
pItemPool = NULL;
|
|
|
|
while(pNode!= NULL)
|
|
{
|
|
|
|
RenderingFX = RenderFXList[ cnt ];
|
|
|
|
fObscured = RenderingFX.fObscured;
|
|
fDynamic = RenderingFX.fDynamic;
|
|
|
|
fMerc = RenderingFX.fMerc;
|
|
fZWrite = RenderingFX.fZWrite;
|
|
fZBlitter = RenderingFX.fZBlitter;
|
|
fShadowBlitter = RenderingFX.fShadowBlitter;
|
|
fLinkedListDirection = RenderingFX.fLinkedListDirection;
|
|
fCheckForRedundency = RenderingFX.fCheckForRedundency;
|
|
fMultiZBlitter = RenderingFX.fMultiZBlitter;
|
|
fConvertTo16 = RenderingFX.fConvertTo16;
|
|
fIntensityBlitter = FALSE;
|
|
fSaveZ = FALSE;
|
|
fWallTile = FALSE;
|
|
gsForceSoldierZLevel = FALSE;
|
|
pSoldier = NULL;
|
|
fUseTileElem = FALSE;
|
|
fMultiTransShadowZBlitter = FALSE;
|
|
fObscuredBlitter = FALSE;
|
|
fTranslucencyType = TRUE;
|
|
uiAniTileFlags = 0;
|
|
sZStripIndex = -1;
|
|
|
|
uiLevelNodeFlags = pNode->uiFlags;
|
|
|
|
if ( fCheckForRedundency )
|
|
{
|
|
if ( ( gpWorldLevelData[ uiTileIndex ].uiFlags & MAPELEMENT_REDUNDENT) )
|
|
{
|
|
// IF WE DONOT WANT TO RE-EVALUATE FIRST
|
|
if ( !( gpWorldLevelData[uiTileIndex].uiFlags & MAPELEMENT_REEVALUATE_REDUNDENCY ) && !(gTacticalStatus.uiFlags & NOHIDE_REDUNDENCY ) )
|
|
{
|
|
pNode = NULL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Force z-buffer blitting for marked tiles ( even ground!)
|
|
if ( (uiFlags&TILES_MARKED) )
|
|
{
|
|
fZBlitter = TRUE;
|
|
}
|
|
|
|
|
|
//Looking up height every time here is alot better than doing it above!
|
|
sTileHeight=gpWorldLevelData[uiTileIndex].sHeight;
|
|
|
|
sModifiedTileHeight = ( ( ( sTileHeight / 80 ) - 1 ) * 80 );
|
|
|
|
if ( sModifiedTileHeight < 0 )
|
|
{
|
|
sModifiedTileHeight = 0;
|
|
}
|
|
|
|
|
|
fRenderTile=TRUE;
|
|
pDirtyBackPtr=NULL;
|
|
if(uiLevelNodeFlags&LEVELNODE_REVEAL)
|
|
{
|
|
if(!fDynamic)
|
|
fRenderTile=FALSE;
|
|
else
|
|
fPixelate=TRUE;
|
|
}
|
|
else
|
|
fPixelate=FALSE;
|
|
|
|
// non-type specific setup
|
|
sXPos = (INT16)iTempPosX_S;
|
|
sYPos = (INT16)iTempPosY_S;
|
|
|
|
|
|
// setup for any tile type except mercs
|
|
if(!fMerc )
|
|
{
|
|
if ( !( uiLevelNodeFlags & ( LEVELNODE_ROTTINGCORPSE | LEVELNODE_CACHEDANITILE ) ) )
|
|
{
|
|
if( ( uiLevelNodeFlags & LEVELNODE_REVEALTREES ) )
|
|
{
|
|
TileElem = &(gTileDatabase[pNode->usIndex + 2]);
|
|
}
|
|
else
|
|
{
|
|
TileElem = &(gTileDatabase[pNode->usIndex]);
|
|
}
|
|
|
|
// HANDLE INDEPENDANT-PER-TILE ANIMATIONS ( IE: DOORS, EXPLODING THINGS, ETC )
|
|
if ( fDynamic )
|
|
{
|
|
if( ( uiLevelNodeFlags & LEVELNODE_ANIMATION ) )
|
|
{
|
|
if ( pNode->sCurrentFrame != -1 )
|
|
{
|
|
Assert( TileElem->pAnimData != NULL );
|
|
TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[pNode->sCurrentFrame]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for best translucency
|
|
if ( uiLevelNodeFlags & LEVELNODE_USEBESTTRANSTYPE )
|
|
{
|
|
fTranslucencyType = FALSE;
|
|
}
|
|
|
|
if ( ( uiLevelNodeFlags & ( LEVELNODE_ROTTINGCORPSE | LEVELNODE_CACHEDANITILE ) ) )
|
|
{
|
|
if ( fDynamic )
|
|
{
|
|
if( !(uiLevelNodeFlags & ( LEVELNODE_DYNAMIC ) ) && !(uiLevelNodeFlags & LEVELNODE_LASTDYNAMIC) )
|
|
fRenderTile=FALSE;
|
|
}
|
|
else if( (uiLevelNodeFlags & ( LEVELNODE_DYNAMIC ) ) )
|
|
fRenderTile=FALSE;
|
|
}
|
|
else
|
|
{
|
|
// Set Tile elem flags here!
|
|
uiTileElemFlags = TileElem->uiFlags;
|
|
// Set valid tile elem!
|
|
fUseTileElem = TRUE;
|
|
|
|
if(fDynamic || fPixelate)
|
|
{
|
|
if(!fPixelate)
|
|
{
|
|
if(!( uiTileElemFlags & ANIMATED_TILE) && !(uiTileElemFlags & DYNAMIC_TILE) && !(uiLevelNodeFlags & LEVELNODE_DYNAMIC) && !(uiLevelNodeFlags & LEVELNODE_LASTDYNAMIC) )
|
|
fRenderTile=FALSE;
|
|
else if(!(uiTileElemFlags&DYNAMIC_TILE) && !(uiLevelNodeFlags&LEVELNODE_DYNAMIC) && !(uiLevelNodeFlags&LEVELNODE_LASTDYNAMIC) )
|
|
// else if((TileElem->uiFlags&ANIMATED_TILE) )
|
|
{
|
|
Assert( TileElem->pAnimData != NULL );
|
|
TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[TileElem->pAnimData->bCurrentFrame]];
|
|
uiTileElemFlags = TileElem->uiFlags;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if((uiTileElemFlags & ANIMATED_TILE) || (uiTileElemFlags & DYNAMIC_TILE) || (uiLevelNodeFlags & LEVELNODE_DYNAMIC) )
|
|
{
|
|
if ( !( uiFlags & TILES_OBSCURED ) || ( uiTileElemFlags & ANIMATED_TILE ) )
|
|
{
|
|
fRenderTile=FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// OK, ATE, CHECK FOR AN OBSCURED TILE AND MAKE SURE IF LEVELNODE IS SET
|
|
// WE DON'T RENDER UNLESS WE HAVE THE RENDER FLAG SET!
|
|
if ( fObscured )
|
|
{
|
|
if ( ( uiFlags & TILES_OBSCURED ) )
|
|
{
|
|
if ( uiLevelNodeFlags & LEVELNODE_SHOW_THROUGH )
|
|
{
|
|
fObscuredBlitter = TRUE;
|
|
|
|
// ATE: Check if this is a levelnode, and what frame we are on
|
|
// turn off......
|
|
//if ( ( uiLevelNodeFlags & LEVELNODE_ITEM ) && gsCurrentItemGlowFrame < 25 )
|
|
//{
|
|
// fRenderTile = FALSE;
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
// Don;t render if we are not on this render loop!
|
|
fRenderTile = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( uiLevelNodeFlags & LEVELNODE_SHOW_THROUGH )
|
|
{
|
|
fRenderTile = FALSE;
|
|
|
|
// ATE: Check if this is a levelnode, and what frame we are on
|
|
// turn off......
|
|
//if ( ( uiLevelNodeFlags & LEVELNODE_ITEM ) && gsCurrentItemGlowFrame < 25 )
|
|
//{
|
|
// fRenderTile = TRUE;
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// If flag says to do dynamic as well, render!
|
|
if ( ( uiFlags & TILES_DOALL ) )
|
|
{
|
|
fRenderTile = TRUE;
|
|
}
|
|
|
|
// If we are on the struct layer, check for if it's hidden!
|
|
if ( uiRowFlags & ( TILES_STATIC_STRUCTURES | TILES_DYNAMIC_STRUCTURES | TILES_STATIC_SHADOWS | TILES_DYNAMIC_SHADOWS ) )
|
|
{
|
|
if ( fUseTileElem )
|
|
{
|
|
#if 0
|
|
// DONOT RENDER IF IT'S A HIDDEN STRUCT AND TILE IS NOT REVEALED
|
|
if ( uiTileElemFlags & HIDDEN_TILE )
|
|
{
|
|
// IF WORLD IS NOT REVEALED, QUIT
|
|
#ifdef JA2EDITOR
|
|
if ( !gfEditMode )
|
|
#endif
|
|
{
|
|
if ( !(gpWorldLevelData[ uiTileIndex ].uiFlags & MAPELEMENT_REVEALED ) && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
|
|
{
|
|
//CONTINUE, DONOT RENDER
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if(fRenderTile)
|
|
{
|
|
// Set flag to set layer as used
|
|
if( fDynamic || fPixelate )
|
|
{
|
|
uiAdditiveLayerUsedFlags |= uiRowFlags;
|
|
}
|
|
|
|
if ( uiLevelNodeFlags & LEVELNODE_DYNAMICZ )
|
|
{
|
|
fSaveZ = TRUE;
|
|
fZWrite = TRUE;
|
|
}
|
|
|
|
if ( ( uiLevelNodeFlags & LEVELNODE_CACHEDANITILE ) )
|
|
{
|
|
hVObject = gpTileCache[ pNode->pAniTile->sCachedTileID ].pImagery->vo;
|
|
usImageIndex = pNode->pAniTile->sCurrentFrame;
|
|
uiAniTileFlags = pNode->pAniTile->uiFlags;
|
|
|
|
// Position corpse based on it's float position
|
|
if ( ( uiLevelNodeFlags & LEVELNODE_ROTTINGCORPSE ) )
|
|
{
|
|
pCorpse = &( gRottingCorpse[ pNode->pAniTile->uiUserData ] );
|
|
|
|
pShadeTable = pCorpse->pShades[ pNode->ubShadeLevel ];
|
|
|
|
//pShadeTable = pCorpse->p16BPPPalette;
|
|
|
|
dOffsetX = pCorpse->def.dXPos - gsRenderCenterX;
|
|
dOffsetY = pCorpse->def.dYPos - gsRenderCenterY;
|
|
|
|
// OK, if this is a corpse.... stop if not visible
|
|
if ( pCorpse->def.bVisible != 1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
|
|
{
|
|
//CONTINUE, DONOT RENDER
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dOffsetX = (FLOAT)( pNode->pAniTile->sRelativeX - gsRenderCenterX );
|
|
dOffsetY = (FLOAT)( pNode->pAniTile->sRelativeY - gsRenderCenterY );
|
|
}
|
|
|
|
// Calculate guy's position
|
|
FloatFromCellToScreenCoordinates( dOffsetX, dOffsetY, &dTempX_S, &dTempY_S );
|
|
|
|
sXPos = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + (INT16)dTempX_S;
|
|
sYPos = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + (INT16)dTempY_S - sTileHeight;
|
|
|
|
// Adjust for offset position on screen
|
|
sXPos -= gsRenderWorldOffsetX;
|
|
sYPos -= gsRenderWorldOffsetY;
|
|
|
|
}
|
|
else
|
|
{
|
|
hVObject = TileElem->hTileSurface;
|
|
usImageIndex=TileElem->usRegionIndex;
|
|
|
|
// ADJUST FOR WORLD MAPELEM HIEGHT
|
|
sYPos-=TileElem->sOffsetHeight;
|
|
|
|
if((TileElem->uiFlags&IGNORE_WORLD_HEIGHT) )
|
|
{
|
|
sYPos = sYPos - sModifiedTileHeight;
|
|
//sYPos -= sTileHeight;
|
|
}
|
|
|
|
if( !(uiLevelNodeFlags&LEVELNODE_IGNOREHEIGHT) && !(TileElem->uiFlags&IGNORE_WORLD_HEIGHT ))
|
|
sYPos-=sTileHeight;
|
|
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
{
|
|
hVObject->pShadeCurrent=hVObject->pShades[pNode->ubShadeLevel];
|
|
hVObject->pShade8=ubColorTables[pNode->ubShadeLevel];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//ADJUST FOR RELATIVE OFFSETS
|
|
if ( uiLevelNodeFlags & LEVELNODE_USERELPOS )
|
|
{
|
|
sXPos += pNode->sRelativeX;
|
|
sYPos += pNode->sRelativeY;
|
|
}
|
|
|
|
if ( uiLevelNodeFlags& LEVELNODE_USEZ )
|
|
{
|
|
sYPos -= pNode->sRelativeZ;
|
|
}
|
|
|
|
//ADJUST FOR ABSOLUTE POSITIONING
|
|
if ( uiLevelNodeFlags& LEVELNODE_USEABSOLUTEPOS )
|
|
{
|
|
dOffsetX = (FLOAT)(pNode->sRelativeX - gsRenderCenterX);
|
|
dOffsetY = (FLOAT)(pNode->sRelativeY - gsRenderCenterY);
|
|
|
|
// OK, DONT'T ASK... CONVERSION TO PROPER Y NEEDS THIS...
|
|
dOffsetX -= CELL_Y_SIZE;
|
|
|
|
FloatFromCellToScreenCoordinates( dOffsetX, dOffsetY, &dTempX_S, &dTempY_S );
|
|
|
|
sXPos = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + (INT16)SHORT_ROUND( dTempX_S );
|
|
sYPos = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + (INT16)SHORT_ROUND( dTempY_S );
|
|
|
|
// Adjust for offset position on screen
|
|
sXPos -= gsRenderWorldOffsetX;
|
|
sYPos -= gsRenderWorldOffsetY;
|
|
|
|
|
|
sYPos -= pNode->sRelativeZ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// COUNT # OF ITEMS AT THIS LOCATION
|
|
if ( uiLevelNodeFlags & LEVELNODE_ITEM )
|
|
{
|
|
// OK set item pool for this location....
|
|
if ( bItemCount == 0 )
|
|
{
|
|
pItemPool = pNode->pItemPool;
|
|
}
|
|
else
|
|
{
|
|
pItemPool = pItemPool->pNext;
|
|
}
|
|
|
|
if ( bItemCount < MAX_RENDERED_ITEMS )
|
|
{
|
|
bItemCount++;
|
|
|
|
if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == VISIBLE )
|
|
{
|
|
bVisibleItemCount++;
|
|
}
|
|
}
|
|
|
|
// LIMIT RENDERING OF ITEMS TO ABOUT 7, DO NOT RENDER HIDDEN ITEMS TOO!
|
|
if ( bVisibleItemCount == MAX_RENDERED_ITEMS || ( gWorldItems[ pItemPool->iItemIndex ].bVisible != VISIBLE ) || ( pItemPool->usFlags & WORLD_ITEM_DONTRENDER ) )
|
|
{
|
|
if ( !(gTacticalStatus.uiFlags&SHOW_ALL_ITEMS) )
|
|
{
|
|
//CONTINUE, DONOT RENDER
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( guiCurrentScreen == EDIT_SCREEN )
|
|
{
|
|
// ATE: If in the editor, change this to a little higher value
|
|
if ( bItemCount == MAX_RENDERED_ITEMS )
|
|
{
|
|
//CONTINUE, DONOT RENDER
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
if ( pItemPool->bRenderZHeightAboveLevel > 0 )
|
|
{
|
|
sYPos -= pItemPool->bRenderZHeightAboveLevel;
|
|
}
|
|
|
|
}
|
|
|
|
// If render tile is false...
|
|
if ( !fRenderTile )
|
|
{
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// specific code for node types on a per-tile basis
|
|
switch( uiRowFlags )
|
|
{
|
|
case TILES_STATIC_LAND:
|
|
|
|
LandZLevel( iTempPosX_M, iTempPosY_M );
|
|
break;
|
|
|
|
case TILES_STATIC_OBJECTS:
|
|
|
|
// ATE: Modified to use constant z level, as these are same level as land items
|
|
ObjectZLevel( TileElem, pNode, iTempPosX_M, iTempPosY_M );
|
|
break;
|
|
|
|
case TILES_STATIC_STRUCTURES:
|
|
|
|
StructZLevel( iTempPosX_M, iTempPosY_M );
|
|
|
|
if ( fUseTileElem && ( TileElem->uiFlags & MULTI_Z_TILE ) )
|
|
{
|
|
fMultiZBlitter = TRUE;
|
|
}
|
|
|
|
// ATE: if we are a wall, set flag
|
|
if ( fUseTileElem && ( TileElem->uiFlags & WALL_TILE ) )
|
|
{
|
|
fWallTile = TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
case TILES_STATIC_ROOF:
|
|
|
|
RoofZLevel( iTempPosX_M, iTempPosY_M );
|
|
|
|
// Automatically adjust height!
|
|
sYPos -= WALL_HEIGHT;
|
|
|
|
// ATE: Added for shadows on roofs
|
|
if ( fUseTileElem && ( TileElem->uiFlags & ROOFSHADOW_TILE ) )
|
|
{
|
|
fShadowBlitter=TRUE;
|
|
}
|
|
break;
|
|
case TILES_STATIC_ONROOF:
|
|
|
|
OnRoofZLevel( iTempPosX_M, iTempPosY_M );
|
|
// Automatically adjust height!
|
|
sYPos -= WALL_HEIGHT;
|
|
break;
|
|
|
|
case TILES_STATIC_TOPMOST:
|
|
|
|
TopmostZLevel( iTempPosX_M, iTempPosY_M );
|
|
break;
|
|
|
|
case TILES_STATIC_SHADOWS:
|
|
|
|
ShadowZLevel( iTempPosX_M, iTempPosY_M );
|
|
|
|
if ( uiLevelNodeFlags & LEVELNODE_EXITGRID )
|
|
{
|
|
fIntensityBlitter = TRUE;
|
|
fShadowBlitter = FALSE;
|
|
}
|
|
break;
|
|
|
|
case TILES_DYNAMIC_LAND:
|
|
|
|
LandZLevel( iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
break;
|
|
case TILES_DYNAMIC_SHADOWS:
|
|
|
|
ShadowZLevel( iTempPosX_M, iTempPosY_M );
|
|
//sZLevel=SHADOW_Z_LEVEL;
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
break;
|
|
case TILES_DYNAMIC_OBJECTS:
|
|
|
|
ObjectZLevel( TileElem, pNode, iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
break;
|
|
|
|
case TILES_DYNAMIC_STRUCTURES:
|
|
|
|
StructZLevel( iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
|
|
if ( uiTileElemFlags & Z_AWARE_DYNAMIC_TILE )
|
|
{
|
|
fMultiZBlitter = TRUE;
|
|
fZBlitter = TRUE;
|
|
fWallTile = TRUE;
|
|
sZStripIndex = 0;
|
|
}
|
|
break;
|
|
case TILES_DYNAMIC_ROOF:
|
|
|
|
sYPos -= WALL_HEIGHT;
|
|
|
|
RoofZLevel( iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
// For now, adjust to hieght of a wall ( 50 temp, make define )
|
|
//if ( TileElem->fType > FOOTPRINTS )
|
|
//{
|
|
// sYPos -= 58;
|
|
//}
|
|
break;
|
|
|
|
case TILES_DYNAMIC_ONROOF:
|
|
|
|
OnRoofZLevel( iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
// Automatically adjust height!
|
|
sYPos -= WALL_HEIGHT;
|
|
break;
|
|
|
|
case TILES_DYNAMIC_TOPMOST:
|
|
TopmostZLevel( iTempPosX_M, iTempPosY_M );
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED;
|
|
break;
|
|
|
|
case TILES_DYNAMIC_MERCS:
|
|
case TILES_DYNAMIC_HIGHMERCS:
|
|
case TILES_DYNAMIC_STRUCT_MERCS:
|
|
|
|
// Set flag to set layer as used
|
|
uiAdditiveLayerUsedFlags |= uiRowFlags;
|
|
|
|
pSoldier=pNode->pSoldier;
|
|
|
|
if ( uiRowFlags == TILES_DYNAMIC_MERCS )
|
|
{
|
|
// If we are multi-tiled, ignore here
|
|
if ( pSoldier->uiStatusFlags & ( SOLDIER_MULTITILE_Z | SOLDIER_Z ) )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
// If we are at a higher level, no not do anything unless we are at the highmerc stage
|
|
if ( pSoldier->bLevel > 0 )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( uiRowFlags == TILES_DYNAMIC_HIGHMERCS )
|
|
{
|
|
// If we are multi-tiled, ignore here
|
|
if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE_Z )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
// If we are at a lower level, no not do anything unless we are at the highmerc stage
|
|
if ( pSoldier->bLevel == 0 )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
if ( uiRowFlags == TILES_DYNAMIC_STRUCT_MERCS )
|
|
{
|
|
// If we are not multi-tiled, ignore here
|
|
if ( !( pSoldier->uiStatusFlags & ( SOLDIER_MULTITILE_Z | SOLDIER_Z ) ) )
|
|
{
|
|
// If we are at a low level, no not do anything unless we are at the merc stage
|
|
if ( pSoldier->bLevel == 0 )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( pSoldier->uiStatusFlags & ( SOLDIER_MULTITILE_Z | SOLDIER_Z ) )
|
|
{
|
|
fSaveZ = TRUE;
|
|
fZBlitter = TRUE;
|
|
|
|
if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE_Z )
|
|
{
|
|
fMultiTransShadowZBlitter = TRUE;
|
|
// ATE: Use one direction for queen!
|
|
if ( pSoldier->ubBodyType == QUEENMONSTER )
|
|
{
|
|
sMultiTransShadowZBlitterIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
sMultiTransShadowZBlitterIndex = gOneCDirection[ pSoldier->bDirection ];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fZWrite = TRUE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// IF we are not active, or are a placeholder for multi-tile animations do nothing
|
|
//if ( !pSoldier->bActive )
|
|
if ( !pSoldier->bActive || (uiLevelNodeFlags & LEVELNODE_MERCPLACEHOLDER) )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
// Skip if we cannot see the guy!
|
|
if ( pSoldier->bLastRenderVisibleValue == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
|
|
// Get animation surface....
|
|
usAnimSurface = GetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
|
|
|
if ( usAnimSurface == INVALID_ANIMATION_SURFACE )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
|
|
// Shade guy always lighter than sceane default!
|
|
{
|
|
UINT8 ubShadeLevel;
|
|
|
|
ubShadeLevel = (pNode->ubShadeLevel&0x0f);
|
|
ubShadeLevel=__max(ubShadeLevel-2, DEFAULT_SHADE_LEVEL);
|
|
ubShadeLevel|=(pNode->ubShadeLevel&0x30);
|
|
|
|
if ( pSoldier->fBeginFade )
|
|
{
|
|
pShadeTable = pSoldier->pCurrentShade = pSoldier->pShades[ pSoldier->ubFadeLevel ];
|
|
}
|
|
else
|
|
{
|
|
pShadeTable = pSoldier->pCurrentShade = pSoldier->pShades[ ubShadeLevel];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Position guy based on guy's position
|
|
dOffsetX = pSoldier->dXPos - gsRenderCenterX;
|
|
dOffsetY = pSoldier->dYPos - gsRenderCenterY;
|
|
|
|
|
|
// Calculate guy's position
|
|
FloatFromCellToScreenCoordinates( dOffsetX, dOffsetY, &dTempX_S, &dTempY_S );
|
|
|
|
sXPos = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + (INT16)dTempX_S;
|
|
sYPos = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + (INT16)dTempY_S - sTileHeight;
|
|
|
|
// Adjust for offset position on screen
|
|
sXPos -= gsRenderWorldOffsetX;
|
|
sYPos -= gsRenderWorldOffsetY;
|
|
|
|
// Adjust for soldier height
|
|
sYPos -= pSoldier->sHeightAdjustment;
|
|
|
|
// Handle shade stuff....
|
|
if ( !pSoldier->fBeginFade )
|
|
{
|
|
// Special effect - draw ghost if is seen by a guy in player's team but not current guy
|
|
// ATE: Todo: setup flag for 'bad-guy' - can releive some checks in renderer
|
|
if ( !pSoldier->bNeutral && (pSoldier->bSide != gbPlayerNum ) )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSelSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
}
|
|
else
|
|
{
|
|
pSelSoldier = NULL;
|
|
}
|
|
|
|
bGlowShadeOffset = 0;
|
|
|
|
if ( gTacticalStatus.ubCurrentTeam == gbPlayerNum )
|
|
{
|
|
// Shade differently depending on visiblity
|
|
if ( pSoldier->bLastRenderVisibleValue == 0 )
|
|
{
|
|
bGlowShadeOffset = 10;
|
|
}
|
|
|
|
if ( pSelSoldier != NULL )
|
|
{
|
|
if ( pSelSoldier->bOppList[ pSoldier->ubID ] != SEEN_CURRENTLY )
|
|
{
|
|
if ( pSoldier->usAnimState != CHARIOTS_OF_FIRE && pSoldier->usAnimState != BODYEXPLODING )
|
|
{
|
|
bGlowShadeOffset = 10;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pSoldier->bLevel == 0 )
|
|
{
|
|
pShadeStart = (INT16 **) &( pSoldier->pGlowShades[ 0 ] );
|
|
}
|
|
else
|
|
{
|
|
pShadeStart = (INT16 **) &( pSoldier->pShades[ 20 ] );
|
|
}
|
|
|
|
// Set shade
|
|
// If a bad guy is highlighted
|
|
if ( gfUIHandleSelectionAboveGuy == TRUE && MercPtrs[ gsSelectedGuy ]->bSide != gbPlayerNum )
|
|
{
|
|
if ( gsSelectedGuy == pSoldier->ubID )
|
|
{
|
|
pShadeTable = (UINT16 *) pShadeStart[ gsGlowFrames[ gsCurrentGlowFrame ] + bGlowShadeOffset ];
|
|
gsForceSoldierZLevel = TOPMOST_Z_LEVEL;
|
|
}
|
|
else
|
|
{
|
|
// Are we dealing with a not-so visible merc?
|
|
if ( bGlowShadeOffset == 10 )
|
|
{
|
|
pShadeTable = pSoldier->pEffectShades[ 0 ];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// OK,not highlighted, but maybe we are in enemy's turn and they have the baton
|
|
|
|
// AI's turn?
|
|
if ( gTacticalStatus.ubCurrentTeam != OUR_TEAM )
|
|
{
|
|
// Does he have baton?
|
|
if ( (pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) )
|
|
{
|
|
pShadeTable = (UINT16 *) pShadeStart[ gpGlowFramePointer[ gsCurrentGlowFrame ] + bGlowShadeOffset ];
|
|
|
|
if ( gpGlowFramePointer[ gsCurrentGlowFrame ] >= 7 )
|
|
{
|
|
gsForceSoldierZLevel = TOPMOST_Z_LEVEL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pShadeTable = (UINT16 *) pShadeStart[ gpGlowFramePointer[ gsCurrentGlowFrame ] + bGlowShadeOffset ];
|
|
|
|
if ( gpGlowFramePointer[ gsCurrentGlowFrame ] >= 7 )
|
|
{
|
|
gsForceSoldierZLevel = TOPMOST_Z_LEVEL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//if ( gusSelectedSoldier != NOBODY )
|
|
//{
|
|
// pSelSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
// Shade differently depending on visiblity
|
|
// if ( pSoldier->bVisible == 0 || ( pSelSoldier->bOppList[ pSoldier->ubID ] == 0 ) )
|
|
// {
|
|
// Shade gray
|
|
// pShadeTable = pSoldier->pGlowShades[ gpGlowFramePointer[ gsCurrentGlowFrame ] + 10 ];
|
|
// }
|
|
//}
|
|
}
|
|
}
|
|
|
|
// Calculate Z level
|
|
SoldierZLevel( pSoldier, iTempPosX_M, iTempPosY_M );
|
|
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
{
|
|
if ( pSoldier->fForceShade )
|
|
{
|
|
pShadeTable = pSoldier->pForcedShade;
|
|
}
|
|
}
|
|
|
|
// check if we are a merc duplicate, if so, only do minimal stuff!
|
|
if ( pSoldier->ubID >= MAX_NUM_SOLDIERS )
|
|
{
|
|
// Shade gray
|
|
pShadeTable = pSoldier->pEffectShades[ 1 ];
|
|
}
|
|
|
|
hVObject=gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject;
|
|
|
|
if ( hVObject == NULL )
|
|
{
|
|
pNode = pNode->pNext;
|
|
continue;
|
|
}
|
|
|
|
// ATE: If we are in a gridno that we should not use obscure blitter, set!
|
|
if ( !( gpWorldLevelData[ uiTileIndex ].ubExtFlags[0] & MAPELEMENT_EXT_NOBURN_STRUCT ) )
|
|
{
|
|
fObscuredBlitter = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// ATE: Artificially increase z=level...
|
|
sZLevel += 2;
|
|
}
|
|
|
|
|
|
usImageIndex=pSoldier->usAniFrame;
|
|
|
|
uiDirtyFlags=BGND_FLAG_SINGLE|BGND_FLAG_ANIMATED| BGND_FLAG_MERC;
|
|
break;
|
|
|
|
}
|
|
|
|
// Adjust for interface level
|
|
sYPos += gsRenderHeight;
|
|
|
|
// OK, check for LEVELNODE HIDDEN...
|
|
fHiddenTile = FALSE;
|
|
|
|
if ( uiLevelNodeFlags & LEVELNODE_HIDDEN )
|
|
{
|
|
fHiddenTile = TRUE;
|
|
|
|
if ( TileElem != NULL )
|
|
{
|
|
// If we are a roof and have SHOW_ALL_ROOFS on, turn off hidden tile check!
|
|
if ( ( TileElem->uiFlags & ROOF_TILE ) && ( gTacticalStatus.uiFlags&SHOW_ALL_ROOFS ) )
|
|
{
|
|
// Turn off
|
|
fHiddenTile = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if( fRenderTile && !fHiddenTile )
|
|
{
|
|
fTileInvisible = FALSE;
|
|
|
|
if ( ( uiLevelNodeFlags & LEVELNODE_ROTTINGCORPSE ) )
|
|
{
|
|
// Set fmerc flag!
|
|
fMerc = TRUE;
|
|
fZWrite = TRUE;
|
|
|
|
//if ( hVObject->ppZStripInfo != NULL )
|
|
{
|
|
sMultiTransShadowZBlitterIndex = GetCorpseStructIndex( &( pCorpse->def ), TRUE );
|
|
fMultiTransShadowZBlitter = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( (uiLevelNodeFlags & LEVELNODE_LASTDYNAMIC ) && !(uiFlags&TILES_DIRTY) )
|
|
{
|
|
// Remove flags!
|
|
pNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC );
|
|
fZWrite = TRUE;
|
|
}
|
|
|
|
if ( uiLevelNodeFlags & LEVELNODE_NOWRITEZ )
|
|
{
|
|
fZWrite = FALSE;
|
|
}
|
|
|
|
|
|
if(uiFlags&TILES_NOZWRITE)
|
|
fZWrite=FALSE;
|
|
|
|
if ( uiFlags & TILES_NOZ )
|
|
{
|
|
fZBlitter = FALSE;
|
|
}
|
|
|
|
|
|
|
|
if ( ( uiLevelNodeFlags & LEVELNODE_WIREFRAME ) )
|
|
{
|
|
if ( !gGameSettings.fOptions[ TOPTION_TOGGLE_WIREFRAME ] )
|
|
{
|
|
fTileInvisible = TRUE;
|
|
}
|
|
}
|
|
|
|
// RENDER
|
|
if ( fTileInvisible )
|
|
{
|
|
|
|
}
|
|
else if ( uiLevelNodeFlags & LEVELNODE_DISPLAY_AP && !( uiFlags&TILES_DIRTY ) )
|
|
{
|
|
pTrav = &(hVObject->pETRLEObject[usImageIndex]);
|
|
sXPos += pTrav->sOffsetX;
|
|
sYPos += pTrav->sOffsetY;
|
|
|
|
if ( gfUIDisplayActionPointsInvalid )
|
|
{
|
|
SetFontBackground( FONT_MCOLOR_BLACK );
|
|
SetFontForeground( FONT_MCOLOR_WHITE );
|
|
}
|
|
else
|
|
{
|
|
SetFontBackground( FONT_MCOLOR_BLACK );
|
|
SetFontForeground( FONT_MCOLOR_WHITE );
|
|
}
|
|
|
|
if ( gfUIDisplayActionPointsBlack )
|
|
{
|
|
SetFontBackground( FONT_MCOLOR_BLACK );
|
|
SetFontForeground( FONT_MCOLOR_BLACK );
|
|
}
|
|
|
|
SetFont( TINYFONT1 );
|
|
SetFontDestBuffer( guiSAVEBUFFER , 0, gsVIEWPORT_WINDOW_START_Y, SCREEN_WIDTH, gsVIEWPORT_WINDOW_END_Y, FALSE );
|
|
VarFindFontCenterCoordinates( sXPos, sYPos, 1, 1, TINYFONT1, &sX, &sY, L"%d", pNode->uiAPCost );
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", pNode->uiAPCost );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
}
|
|
else if ( ( uiLevelNodeFlags & LEVELNODE_ERASEZ ) && !( uiFlags&TILES_DIRTY ) )
|
|
{
|
|
Zero8BPPDataTo16BPPBufferTransparent( (UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex );
|
|
//Zero8BPPDataTo16BPPBufferTransparent( (UINT16*)gpZBuffer, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex );
|
|
}
|
|
else if ( ( uiLevelNodeFlags & LEVELNODE_ITEM ) && !( uiFlags&TILES_DIRTY ) )
|
|
{
|
|
BOOLEAN fZBlit = FALSE;
|
|
|
|
if ( uiRowFlags == TILES_STATIC_ONROOF || uiRowFlags == TILES_DYNAMIC_ONROOF )
|
|
{
|
|
usOutlineColor = gusYellowItemOutlineColor;
|
|
bItemOutline = TRUE;
|
|
fZBlit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
usOutlineColor = gusNormalItemOutlineColor;
|
|
bItemOutline = TRUE;
|
|
fZBlit = TRUE;
|
|
}
|
|
|
|
if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] )
|
|
{
|
|
if ( uiRowFlags == TILES_STATIC_ONROOF || uiRowFlags == TILES_DYNAMIC_ONROOF )
|
|
{
|
|
usOutlineColor = us16BPPItemCycleYellowColors[ gsCurrentItemGlowFrame ];
|
|
bItemOutline = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ( gTacticalStatus.uiFlags & RED_ITEM_GLOW_ON )
|
|
{
|
|
usOutlineColor = us16BPPItemCycleRedColors[ gsCurrentItemGlowFrame ];
|
|
bItemOutline = TRUE;
|
|
}
|
|
else
|
|
{
|
|
usOutlineColor = us16BPPItemCycleWhiteColors[ gsCurrentItemGlowFrame ];
|
|
bItemOutline = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//else
|
|
//{
|
|
// usOutlineColor = us16BPPItemCycleWhiteColors[ pItemPool->bFlashColor ];
|
|
// bItemOutline = TRUE;
|
|
//}
|
|
|
|
bBlitClipVal = BltIsClippedOrOffScreen(hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
if ( bBlitClipVal == FALSE )
|
|
{
|
|
if ( fZBlit )
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineZPixelateObscured( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutline((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline );
|
|
}
|
|
}
|
|
else if ( bBlitClipVal == TRUE )
|
|
{
|
|
if ( fZBlit )
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineZPixelateObscuredClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline, &gClippingRect );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline, &gClippingRect );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline, &gClippingRect );
|
|
}
|
|
}
|
|
}
|
|
// ATE: Check here for a lot of conditions!
|
|
else if ( ( ( uiLevelNodeFlags & LEVELNODE_PHYSICSOBJECT ) ) && !( uiFlags&TILES_DIRTY ) )
|
|
{
|
|
bItemOutline = TRUE;
|
|
|
|
if ( uiLevelNodeFlags & LEVELNODE_PHYSICSOBJECT )
|
|
{
|
|
bItemOutline = FALSE;
|
|
}
|
|
|
|
bBlitClipVal = BltIsClippedOrOffScreen(hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
if ( fShadowBlitter )
|
|
{
|
|
if ( bBlitClipVal == FALSE )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferShadowZNB( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferShadowZNBClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( bBlitClipVal == FALSE )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline );
|
|
}
|
|
else if ( bBlitClipVal == TRUE )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, usOutlineColor, bItemOutline, &gClippingRect );
|
|
}
|
|
}
|
|
}
|
|
else if(uiFlags&TILES_DIRTY)
|
|
{
|
|
|
|
if ( !(uiLevelNodeFlags & LEVELNODE_LASTDYNAMIC ) )
|
|
{
|
|
pTrav = &(hVObject->pETRLEObject[usImageIndex]);
|
|
uiBrushHeight = (UINT32)pTrav->usHeight;
|
|
uiBrushWidth = (UINT32)pTrav->usWidth;
|
|
sXPos += pTrav->sOffsetX;
|
|
sYPos += pTrav->sOffsetY;
|
|
|
|
RegisterBackgroundRect(uiDirtyFlags, NULL, sXPos, sYPos, (INT16)(sXPos + uiBrushWidth), (INT16)(__min((INT16)(sYPos + uiBrushHeight), gsVIEWPORT_WINDOW_END_Y)));
|
|
|
|
if ( fSaveZ )
|
|
{
|
|
RegisterBackgroundRect(uiDirtyFlags | BGND_FLAG_SAVE_Z, NULL, sXPos, sYPos, (INT16)(sXPos + uiBrushWidth), (INT16)(__min((INT16)(sYPos + uiBrushHeight), gsVIEWPORT_WINDOW_END_Y)));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(gbPixelDepth==16)
|
|
{
|
|
/*if(fConvertTo16)
|
|
{
|
|
ConvertVObjectRegionTo16BPP(hVObject, usImageIndex, 4);
|
|
if(CheckFor16BPPRegion(hVObject, usImageIndex, 4, &us16BPPIndex))
|
|
{
|
|
Blt16BPPDataTo16BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, us16BPPIndex, &gClippingRect);
|
|
}
|
|
}*/
|
|
|
|
if( fMultiTransShadowZBlitter )
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect, sMultiTransShadowZBlitterIndex, pShadeTable );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZTransShadowIncClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect, sMultiTransShadowZBlitterIndex, pShadeTable );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Blt8BPPDataTo16BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect );
|
|
}
|
|
}
|
|
else if( fMultiZBlitter )
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZIncObscureClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
if ( fWallTile )
|
|
{
|
|
if ( sZStripIndex == -1 )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZIncClipZSameZBurnsThrough((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect, usImageIndex);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZIncClipZSameZBurnsThrough((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect, sZStripIndex );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZIncClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bBlitClipVal = BltIsClippedOrOffScreen(hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
if ( bBlitClipVal == TRUE )
|
|
{
|
|
if(fPixelate)
|
|
{
|
|
if(fTranslucencyType)
|
|
{
|
|
//if(fZWrite)
|
|
// Blt8BPPDataTo16BPPBufferTransZClipTranslucent((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
//else
|
|
Blt8BPPDataTo16BPPBufferTransZNBClipTranslucent((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
//if(fZWrite)
|
|
// Blt8BPPDataTo16BPPBufferTransZClipPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
//else
|
|
Blt8BPPDataTo16BPPBufferTransZNBClipPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
}
|
|
else if(fMerc)
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if ( fZWrite )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowZClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
}
|
|
else
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
|
|
Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowZNBClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
}
|
|
}
|
|
|
|
if ( (uiLevelNodeFlags & LEVELNODE_UPDATESAVEBUFFERONCE ) )
|
|
{
|
|
pSaveBuf = LockVideoSurface(guiSAVEBUFFER, &uiSaveBufferPitchBYTES );
|
|
|
|
// BLIT HERE
|
|
Blt8BPPDataTo16BPPBufferTransShadowClip( (UINT16*)pSaveBuf, uiSaveBufferPitchBYTES,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
|
|
UnLockVideoSurface(guiSAVEBUFFER);
|
|
|
|
// Turn it off!
|
|
pNode->uiFlags &= ( ~LEVELNODE_UPDATESAVEBUFFERONCE );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowClip( (UINT16*)pDestBuf, uiDestPitchBYTES,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
}
|
|
}
|
|
else if(fShadowBlitter)
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferShadowZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferShadowZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferShadowClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
}
|
|
else if( fIntensityBlitter)
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferIntensityZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferIntensityZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferIntensityClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
}
|
|
else if(fZBlitter)
|
|
{
|
|
if(fZWrite)
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZNBClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
|
|
if ( (uiLevelNodeFlags & LEVELNODE_UPDATESAVEBUFFERONCE ) )
|
|
{
|
|
pSaveBuf = LockVideoSurface(guiSAVEBUFFER, &uiSaveBufferPitchBYTES );
|
|
|
|
// BLIT HERE
|
|
Blt8BPPDataTo16BPPBufferTransZClip((UINT16*)pSaveBuf, uiSaveBufferPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
UnLockVideoSurface(guiSAVEBUFFER);
|
|
|
|
// Turn it off!
|
|
pNode->uiFlags &= ( ~LEVELNODE_UPDATESAVEBUFFERONCE );
|
|
}
|
|
|
|
}
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
}
|
|
else if ( bBlitClipVal == FALSE )
|
|
{
|
|
if(fPixelate)
|
|
{
|
|
if(fTranslucencyType)
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferTransZTranslucent((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransZNBTranslucent((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferTransZPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransZNBPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
else if(fMerc)
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if ( fZWrite )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowZ( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
}
|
|
else
|
|
{
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransShadowZNB( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
}
|
|
}
|
|
|
|
if ( (uiLevelNodeFlags & LEVELNODE_UPDATESAVEBUFFERONCE ) )
|
|
{
|
|
pSaveBuf = LockVideoSurface(guiSAVEBUFFER, &uiSaveBufferPitchBYTES );
|
|
|
|
// BLIT HERE
|
|
Blt8BPPDataTo16BPPBufferTransShadow( (UINT16*)pSaveBuf, uiSaveBufferPitchBYTES,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
|
|
UnLockVideoSurface(guiSAVEBUFFER);
|
|
|
|
// Turn it off!
|
|
pNode->uiFlags &= ( ~LEVELNODE_UPDATESAVEBUFFERONCE );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
Blt8BPPDataTo16BPPBufferTransShadow( (UINT16*)pDestBuf, uiDestPitchBYTES,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
}
|
|
}
|
|
else if(fShadowBlitter)
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferShadowZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferShadowZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferShadow((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
else if( fIntensityBlitter )
|
|
{
|
|
if ( fZBlitter )
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo16BPPBufferIntensityZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferIntensityZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferIntensity((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
else if(fZBlitter)
|
|
{
|
|
if(fZWrite)
|
|
{
|
|
// TEST
|
|
//Blt8BPPDataTo16BPPBufferTransZPixelate( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
|
|
if ( fObscuredBlitter )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZPixelateObscured( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferTransZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
|
|
|
|
if ( (uiLevelNodeFlags & LEVELNODE_UPDATESAVEBUFFERONCE ) )
|
|
{
|
|
pSaveBuf = LockVideoSurface(guiSAVEBUFFER, &uiSaveBufferPitchBYTES );
|
|
|
|
// BLIT HERE
|
|
Blt8BPPDataTo16BPPBufferTransZ((UINT16*)pSaveBuf, uiSaveBufferPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex );
|
|
|
|
UnLockVideoSurface(guiSAVEBUFFER);
|
|
|
|
// Turn it off!
|
|
pNode->uiFlags &= ( ~LEVELNODE_UPDATESAVEBUFFERONCE );
|
|
}
|
|
|
|
}
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
}
|
|
else // 8bpp section
|
|
{
|
|
if(fPixelate)
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo8BPPBufferTransZClipPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransZNBClipPixelate((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else if(BltIsClipped(hVObject, sXPos, sYPos, usImageIndex, &gClippingRect))
|
|
{
|
|
if(fMerc)
|
|
{
|
|
Blt8BPPDataTo8BPPBufferTransShadowZNBClip( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
&gClippingRect,
|
|
pShadeTable);
|
|
}
|
|
else if(fShadowBlitter)
|
|
if(fZWrite)
|
|
Blt8BPPDataTo8BPPBufferShadowZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferShadowZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
|
|
else if(fZBlitter)
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo8BPPBufferTransZClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransZNBClip((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex, &gClippingRect);
|
|
}
|
|
else
|
|
{
|
|
if(fMerc)
|
|
{
|
|
|
|
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
hVObject,
|
|
sXPos, sYPos,
|
|
usImageIndex,
|
|
pShadeTable);
|
|
|
|
|
|
// Blt8BPPDataTo8BPPBufferTransShadowZNB( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel,
|
|
// hVObject,
|
|
// sXPos, sYPos,
|
|
// usImageIndex,
|
|
// pShadeTable);
|
|
}
|
|
else if(fShadowBlitter)
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo8BPPBufferShadowZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferShadowZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else if(fZBlitter)
|
|
{
|
|
if(fZWrite)
|
|
Blt8BPPDataTo8BPPBufferTransZ((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransZNB((UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
// RENDR APS ONTOP OF PLANNED MERC GUY
|
|
if ( fRenderTile && !( uiFlags&TILES_DIRTY ) )
|
|
{
|
|
if ( fMerc )
|
|
{
|
|
if ( pSoldier != NULL && pSoldier->ubID >= MAX_NUM_SOLDIERS )
|
|
{
|
|
SetFont( TINYFONT1 );
|
|
SetFontDestBuffer( guiSAVEBUFFER , 0, gsVIEWPORT_WINDOW_START_Y, SCREEN_WIDTH, gsVIEWPORT_WINDOW_END_Y, FALSE );
|
|
VarFindFontCenterCoordinates( sXPos, sYPos, 1, 1, TINYFONT1, &sX, &sY, L"%d", pSoldier->ubPlannedUIAPCost );
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", pSoldier->ubPlannedUIAPCost );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(!fLinkedListDirection)
|
|
pNode = pNode->pPrevNode;
|
|
else
|
|
pNode = pNode->pNext;
|
|
|
|
//pNode = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( gfEditMode )
|
|
{
|
|
//ATE: Used here in the editor to denote then an area is not in the world
|
|
|
|
//Kris: Fixed a couple things here...
|
|
// First, there was a problem with the FRAME_BUFFER already being locked which caused failures,
|
|
// and eventual crashes, so if it reaches this code, the buffer needs to be unlocked first, as
|
|
// it gets locked and unlocked internally within ColorFillVideoSurfaceArea(). I'm surprised
|
|
// this problem didn't surface a long time ago. Anyway, it seems that scrolling to the bottom
|
|
// right hand corner of the map, would cause the end of the world to be drawn. Now, this would
|
|
// only crash on my computer and not Emmons, so this should work. Also, I changed the color
|
|
// from fluorescent green to black, which is easier on the eyes, and prevent the drawing of the
|
|
// end of the world if it would be drawn on the editor's taskbar.
|
|
if( iTempPosY_S < INTERFACE_START_Y )
|
|
{
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
ColorFillVideoSurfaceArea( FRAME_BUFFER, iTempPosX_S, iTempPosY_S, (INT16)(iTempPosX_S + 40),
|
|
(INT16)( min( iTempPosY_S + 20, INTERFACE_START_Y )), Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
}
|
|
}
|
|
}
|
|
|
|
iTempPosX_S += 40;
|
|
iTempPosX_M ++;
|
|
iTempPosY_M --;
|
|
|
|
if ( iTempPosX_S >= iEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
}
|
|
|
|
}
|
|
// } while( FALSE );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
iAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
iAnchorPosX_M ++;
|
|
}
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
iAnchorPosY_S += 10;
|
|
|
|
if ( iAnchorPosY_S >= iEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
if(!(uiFlags&TILES_DIRTY))
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
if ( uiFlags & TILES_DYNAMIC_CHECKFOR_INT_TILE )
|
|
{
|
|
EndCurInteractiveTileCheck( );
|
|
}
|
|
|
|
|
|
}
|
|
/// kONIE Renderowania klastra
|
|
|
|
|
|
void DeleteFromWorld( UINT16 usTileIndex, UINT32 uiRenderTiles, UINT16 usIndex )
|
|
{
|
|
switch( uiRenderTiles )
|
|
{
|
|
case TILES_DYNAMIC_LAND:
|
|
case TILES_STATIC_LAND:
|
|
RemoveLand( usTileIndex, usIndex );
|
|
break;
|
|
case TILES_DYNAMIC_OBJECTS:
|
|
case TILES_STATIC_OBJECTS:
|
|
RemoveObject( usTileIndex, usIndex );
|
|
break;
|
|
case TILES_STATIC_STRUCTURES:
|
|
case TILES_DYNAMIC_STRUCTURES:
|
|
RemoveStruct( usTileIndex, usIndex );
|
|
break;
|
|
case TILES_DYNAMIC_ROOF:
|
|
case TILES_STATIC_ROOF:
|
|
RemoveRoof( usTileIndex, usIndex );
|
|
break;
|
|
case TILES_STATIC_ONROOF:
|
|
RemoveOnRoof( usTileIndex, usIndex );
|
|
break;
|
|
|
|
case TILES_DYNAMIC_TOPMOST:
|
|
case TILES_STATIC_TOPMOST:
|
|
RemoveTopmost( usTileIndex, usIndex );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// memcpy's the background to the new scroll position, and renders the missing strip
|
|
// via the RenderStaticWorldRect. Dynamic stuff will be updated on the next frame
|
|
// by the normal render cycle
|
|
void ScrollBackground(UINT32 uiDirection, INT16 sScrollXIncrement, INT16 sScrollYIncrement )
|
|
{
|
|
|
|
//RestoreBackgroundRects();
|
|
|
|
if ( !gfDoVideoScroll )
|
|
{
|
|
// Clear z-buffer
|
|
memset(gpZBuffer, LAND_Z_LEVEL, SCREEN_WIDTH*2* gsVIEWPORT_END_Y );
|
|
|
|
RenderStaticWorldRect( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y, FALSE );
|
|
|
|
FreeBackgroundRectType(BGND_FLAG_ANIMATED);
|
|
}
|
|
else
|
|
{
|
|
if ( gfRenderScroll == FALSE )
|
|
{
|
|
guiScrollDirection = uiDirection;
|
|
gfScrollStart = TRUE;
|
|
gsScrollXIncrement = 0;
|
|
gsScrollYIncrement = 0;
|
|
}
|
|
else
|
|
{
|
|
guiScrollDirection |= uiDirection;
|
|
gfScrollStart = FALSE;
|
|
|
|
}
|
|
|
|
gfRenderScroll = TRUE;
|
|
gsScrollXIncrement += sScrollXIncrement;
|
|
gsScrollYIncrement += sScrollYIncrement;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Render routine takes center X, Y and Z coordinate and gets world
|
|
// Coordinates for the window from that using the following functions
|
|
// For coordinate transformations
|
|
|
|
void RenderWorld( )
|
|
{
|
|
TILE_ELEMENT *TileElem;
|
|
TILE_ANIMATION_DATA *pAnimData;
|
|
UINT32 cnt = 0;
|
|
|
|
gfRenderFullThisFrame = FALSE;
|
|
|
|
// If we are testing renderer, set background to pink!
|
|
if ( gTacticalStatus.uiFlags & DEBUGCLIFFS )
|
|
{
|
|
ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, gsVIEWPORT_WINDOW_START_Y, SCREEN_WIDTH, gsVIEWPORT_WINDOW_END_Y, Get16BPPColor( FROMRGB( 0, 255, 0 ) ) );
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
}
|
|
|
|
if ( gTacticalStatus.uiFlags & SHOW_Z_BUFFER )
|
|
{
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
}
|
|
|
|
|
|
// SetRenderFlags(RENDER_FLAG_FULL);
|
|
|
|
|
|
|
|
// FOR NOW< HERE, UPDATE ANIMATED TILES
|
|
if ( COUNTERDONE( ANIMATETILES ) )
|
|
{
|
|
RESETCOUNTER( ANIMATETILES );
|
|
|
|
while( cnt < gusNumAnimatedTiles )
|
|
{
|
|
TileElem = &(gTileDatabase[ gusAnimatedTiles[ cnt ] ] );
|
|
|
|
pAnimData = TileElem->pAnimData;
|
|
|
|
Assert( pAnimData != NULL );
|
|
|
|
pAnimData->bCurrentFrame++;
|
|
|
|
if ( pAnimData->bCurrentFrame >= pAnimData->ubNumFrames )
|
|
pAnimData->bCurrentFrame = 0;
|
|
cnt++;
|
|
}
|
|
}
|
|
|
|
// HERE, UPDATE GLOW INDEX
|
|
if ( COUNTERDONE( GLOW_ENEMYS ) )
|
|
{
|
|
RESETCOUNTER( GLOW_ENEMYS );
|
|
|
|
gsCurrentGlowFrame++;
|
|
|
|
if ( gsCurrentGlowFrame == NUM_GLOW_FRAMES )
|
|
{
|
|
gsCurrentGlowFrame = 0;
|
|
}
|
|
|
|
gsCurrentItemGlowFrame++;
|
|
|
|
if ( gsCurrentItemGlowFrame == NUM_ITEM_CYCLE_COLORS )
|
|
{
|
|
gsCurrentItemGlowFrame = 0;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//RenderStaticWorldRect( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
//AddBaseDirtyRect(gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
//return;
|
|
|
|
|
|
//#if 0
|
|
|
|
if(gRenderFlags&RENDER_FLAG_FULL)
|
|
{
|
|
gfRenderFullThisFrame = TRUE;
|
|
|
|
gfTopMessageDirty = TRUE;
|
|
|
|
// Dirty the interface...
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
|
|
// Apply scrolling sets some world variables
|
|
ApplyScrolling( gsRenderCenterX, gsRenderCenterY, TRUE, FALSE );
|
|
ResetLayerOptimizing();
|
|
|
|
if ( (gRenderFlags&RENDER_FLAG_NOZ ) )
|
|
{
|
|
RenderStaticWorldRect( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y, FALSE );
|
|
|
|
}
|
|
else
|
|
{
|
|
RenderStaticWorld();
|
|
|
|
}
|
|
|
|
|
|
if(!(gRenderFlags&RENDER_FLAG_SAVEOFF))
|
|
UpdateSaveBuffer();
|
|
|
|
|
|
}
|
|
else if(gRenderFlags&RENDER_FLAG_MARKED)
|
|
{
|
|
ResetLayerOptimizing();
|
|
RenderMarkedWorld();
|
|
if(!(gRenderFlags&RENDER_FLAG_SAVEOFF))
|
|
UpdateSaveBuffer();
|
|
|
|
}
|
|
|
|
if ( gfScrollInertia == FALSE || (gRenderFlags&RENDER_FLAG_NOZ ) || (gRenderFlags&RENDER_FLAG_FULL ) || (gRenderFlags&RENDER_FLAG_MARKED ) )
|
|
{
|
|
RenderDynamicWorld( );
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// ColorFillVideoSurfaceArea( guiSAVEBUFFER, 0, gsVIEWPORT_WINDOW_END_Y, BP_SCREEN_WIDTH_CENTERED, SCREEN_HEIGHT, Get16BPPColor( FROMRGB( 16, 8, 0 ) ) );
|
|
|
|
///////////////////////////////////////////////////////////
|
|
}
|
|
|
|
if ( gfScrollInertia )
|
|
{
|
|
EmptyBackgroundRects( );
|
|
}
|
|
|
|
if( gRenderFlags&RENDER_FLAG_ROOMIDS )
|
|
{
|
|
RenderRoomInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if( gRenderFlags&RENDER_FLAG_FOVDEBUG )
|
|
{
|
|
RenderFOVDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
else if (gfDisplayCoverValues)
|
|
{
|
|
RenderCoverDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
else if (gfDisplayGridNoVisibleValues)
|
|
{
|
|
RenderGridNoVisibleDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
|
|
#endif
|
|
|
|
//#endif
|
|
|
|
//RenderStaticWorldRect( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
//AddBaseDirtyRect(gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
|
|
|
|
if(gRenderFlags&RENDER_FLAG_MARKED)
|
|
ClearMarkedTiles();
|
|
|
|
if ( gRenderFlags&RENDER_FLAG_CHECKZ && !(gTacticalStatus.uiFlags & NOHIDE_REDUNDENCY) )
|
|
{
|
|
ExamineZBufferRect( gsVIEWPORT_START_X, gsVIEWPORT_WINDOW_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y );
|
|
}
|
|
|
|
|
|
gRenderFlags&=(~(RENDER_FLAG_FULL|RENDER_FLAG_MARKED|RENDER_FLAG_ROOMIDS|RENDER_FLAG_CHECKZ));
|
|
|
|
if ( gTacticalStatus.uiFlags & SHOW_Z_BUFFER )
|
|
{
|
|
// COPY Z BUFFER TO FRAME BUFFER
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT16 *pDestBuf;
|
|
UINT32 cnt;
|
|
INT16 zVal;
|
|
|
|
pDestBuf = (UINT16 *)LockVideoSurface(guiRENDERBUFFER, &uiDestPitchBYTES);
|
|
|
|
for ( cnt = 0; cnt < (UINT32)( SCREEN_WIDTH * SCREEN_HEIGHT ); cnt++ )
|
|
{
|
|
// Get Z value
|
|
zVal = gpZBuffer[ cnt ];
|
|
pDestBuf[cnt] = zVal;
|
|
}
|
|
|
|
UnLockVideoSurface(guiRENDERBUFFER);
|
|
}
|
|
|
|
}
|
|
|
|
// Start with a center X,Y,Z world coordinate and render direction
|
|
// Determine WorldIntersectionPoint and the starting block from these
|
|
// Then render away!
|
|
|
|
//ok tutaj jest renderowane przy przesuwaniu
|
|
void RenderStaticWorldRect(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom, BOOLEAN fDynamicsToo )
|
|
{
|
|
UINT32 uiLevelFlags[10];
|
|
UINT16 sLevelIDs[10];
|
|
|
|
// Calculate render starting parameters
|
|
CalcRenderParameters( sLeft, sTop, sRight, sBottom );
|
|
|
|
memset(gpZBuffer, LAND_Z_LEVEL, 2280 * gsVIEWPORT_END_Y );
|
|
|
|
|
|
// Reset layer optimizations
|
|
ResetLayerOptimizing( );
|
|
//#if 0
|
|
|
|
// rendering land
|
|
uiLevelFlags[0] = TILES_STATIC_LAND;
|
|
sLevelIDs [0] = RENDER_STATIC_LAND;
|
|
RenderTiles( 0 , gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
//rendering objects
|
|
uiLevelFlags[0] = TILES_STATIC_OBJECTS;
|
|
sLevelIDs [0] = RENDER_STATIC_OBJECTS;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
if(gRenderFlags&RENDER_FLAG_SHADOWS )
|
|
{
|
|
// If we have to we render shadows
|
|
uiLevelFlags[0] = TILES_STATIC_SHADOWS;
|
|
sLevelIDs [0] = RENDER_STATIC_SHADOWS;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags , sLevelIDs );
|
|
}
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_STRUCTURES;
|
|
sLevelIDs [0] = RENDER_STATIC_STRUCTS;
|
|
uiLevelFlags[1] = TILES_STATIC_ROOF;
|
|
sLevelIDs [1] = RENDER_STATIC_ROOF;
|
|
uiLevelFlags[2] = TILES_STATIC_ONROOF;
|
|
sLevelIDs [2] = RENDER_STATIC_ONROOF;
|
|
uiLevelFlags[3] = TILES_STATIC_TOPMOST;
|
|
sLevelIDs [3] = RENDER_STATIC_TOPMOST;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 4, uiLevelFlags, sLevelIDs );
|
|
|
|
//ATE: Do obsucred layer!
|
|
uiLevelFlags[0] = TILES_STATIC_STRUCTURES;
|
|
sLevelIDs[0] = RENDER_STATIC_STRUCTS;
|
|
uiLevelFlags[1] = TILES_STATIC_ONROOF;
|
|
sLevelIDs[1] = RENDER_STATIC_ONROOF;
|
|
RenderTiles( TILES_OBSCURED, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 2, uiLevelFlags, sLevelIDs );
|
|
|
|
|
|
uiLevelFlags[0] = TILES_DYNAMIC_MERCS;
|
|
//uiLevelFlags[1] = TILES_DYNAMIC_HIGHMERCS;
|
|
|
|
sLevelIDs[0] = RENDER_DYNAMIC_MERCS;
|
|
//sLevelIDs[1] = RENDER_DYNAMIC_HIGHMERCS;
|
|
RenderTiles( 0, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
|
|
if ( fDynamicsToo )
|
|
{
|
|
// DYNAMICS
|
|
uiLevelFlags[0] = TILES_DYNAMIC_LAND;
|
|
uiLevelFlags[1] = TILES_DYNAMIC_OBJECTS;
|
|
uiLevelFlags[2] = TILES_DYNAMIC_SHADOWS;
|
|
uiLevelFlags[3] = TILES_DYNAMIC_STRUCT_MERCS;
|
|
uiLevelFlags[4] = TILES_DYNAMIC_MERCS;
|
|
uiLevelFlags[5] = TILES_DYNAMIC_STRUCTURES;
|
|
uiLevelFlags[6] = TILES_DYNAMIC_ROOF;
|
|
uiLevelFlags[7] = TILES_DYNAMIC_HIGHMERCS;
|
|
uiLevelFlags[8] = TILES_DYNAMIC_ONROOF;
|
|
|
|
sLevelIDs[0] = RENDER_DYNAMIC_LAND;
|
|
sLevelIDs[1] = RENDER_DYNAMIC_OBJECTS;
|
|
sLevelIDs[2] = RENDER_DYNAMIC_SHADOWS;
|
|
sLevelIDs[3] = RENDER_DYNAMIC_STRUCT_MERCS;
|
|
sLevelIDs[4] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[5] = RENDER_DYNAMIC_STRUCTS;
|
|
sLevelIDs[6] = RENDER_DYNAMIC_ROOF;
|
|
sLevelIDs[7] = RENDER_DYNAMIC_HIGHMERCS;
|
|
sLevelIDs[8] = RENDER_DYNAMIC_ONROOF;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 9, uiLevelFlags , sLevelIDs );
|
|
|
|
|
|
SumAddiviveLayerOptimization( );
|
|
}
|
|
|
|
ResetRenderParameters( );
|
|
|
|
if ( !gfDoVideoScroll )
|
|
{
|
|
//AddBaseDirtyRect(gsVIEWPORT_START_X, gsVIEWPORT_WINDOW_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y );
|
|
AddBaseDirtyRect(sLeft, sTop, sRight, sBottom );
|
|
}
|
|
|
|
//#endif
|
|
}
|
|
|
|
|
|
// to jest wykonywane przy kazdym takcie zegara
|
|
void RenderStaticWorld( )
|
|
{
|
|
UINT32 uiLevelFlags[9];
|
|
UINT16 sLevelIDs[9];
|
|
|
|
// Calculate render starting parameters
|
|
CalcRenderParameters( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
|
|
// Clear z-buffer
|
|
memset(gpZBuffer, LAND_Z_LEVEL, 2280 * gsVIEWPORT_END_Y );
|
|
|
|
FreeBackgroundRectType(BGND_FLAG_ANIMATED);
|
|
InvalidateBackgroundRects();
|
|
|
|
// rendering land tiles
|
|
uiLevelFlags[0] = TILES_STATIC_LAND;
|
|
sLevelIDs [0] = RENDER_STATIC_LAND;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
//rendering objects
|
|
uiLevelFlags[0] = TILES_STATIC_OBJECTS;
|
|
sLevelIDs [0] = RENDER_STATIC_OBJECTS;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
// If we have to we render shadows
|
|
if(gRenderFlags&RENDER_FLAG_SHADOWS )
|
|
{
|
|
uiLevelFlags[0] = TILES_STATIC_SHADOWS;
|
|
sLevelIDs [0] = RENDER_STATIC_SHADOWS;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 1, uiLevelFlags , sLevelIDs );
|
|
}
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_STRUCTURES;
|
|
sLevelIDs [0] = RENDER_STATIC_STRUCTS;
|
|
uiLevelFlags[1] = TILES_STATIC_ROOF;
|
|
sLevelIDs [1] = RENDER_STATIC_ROOF;
|
|
uiLevelFlags[2] = TILES_STATIC_ONROOF;
|
|
sLevelIDs [2] = RENDER_STATIC_ONROOF;
|
|
uiLevelFlags[3] = TILES_STATIC_TOPMOST;
|
|
sLevelIDs [3] = RENDER_STATIC_TOPMOST;
|
|
RenderTiles( 0, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 4, uiLevelFlags, sLevelIDs );
|
|
|
|
//ATE: Do obsucred layer!
|
|
uiLevelFlags[0] = TILES_STATIC_STRUCTURES;
|
|
sLevelIDs[0] = RENDER_STATIC_STRUCTS;
|
|
uiLevelFlags[1] = TILES_STATIC_ONROOF;
|
|
sLevelIDs[1] = RENDER_STATIC_ONROOF;
|
|
RenderTiles( TILES_OBSCURED, gsLStartPointX_M, gsLStartPointY_M, gsLStartPointX_S, gsLStartPointY_S, gsLEndXS, gsLEndYS, 2, uiLevelFlags, sLevelIDs );
|
|
|
|
|
|
AddBaseDirtyRect(gsVIEWPORT_START_X, gsVIEWPORT_WINDOW_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y );
|
|
ResetRenderParameters( );
|
|
|
|
}
|
|
|
|
void RenderMarkedWorld(void)
|
|
{
|
|
UINT32 uiLevelFlags[4];
|
|
UINT16 sLevelIDs[4];
|
|
|
|
CalcRenderParameters( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
|
|
|
|
|
|
RestoreBackgroundRects();
|
|
FreeBackgroundRectType(BGND_FLAG_ANIMATED);
|
|
InvalidateBackgroundRects();
|
|
|
|
ResetLayerOptimizing();
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_LAND;
|
|
uiLevelFlags[1] = TILES_STATIC_OBJECTS;
|
|
sLevelIDs[0] = RENDER_STATIC_LAND;
|
|
sLevelIDs[1] = RENDER_STATIC_OBJECTS;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 2, uiLevelFlags, sLevelIDs );
|
|
|
|
if(gRenderFlags&RENDER_FLAG_SHADOWS)
|
|
{
|
|
uiLevelFlags[0] = TILES_STATIC_SHADOWS;
|
|
sLevelIDs[0] = RENDER_STATIC_SHADOWS;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
}
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_STRUCTURES;
|
|
sLevelIDs[0] = RENDER_STATIC_STRUCTS;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_ROOF;
|
|
sLevelIDs[0] = RENDER_STATIC_ROOF;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_ONROOF;
|
|
sLevelIDs[0] = RENDER_STATIC_ONROOF;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
uiLevelFlags[0] = TILES_STATIC_TOPMOST;
|
|
sLevelIDs[0] = RENDER_STATIC_TOPMOST;
|
|
RenderTiles(TILES_MARKED, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
|
|
AddBaseDirtyRect(gsVIEWPORT_START_X, gsVIEWPORT_WINDOW_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y );
|
|
|
|
|
|
ResetRenderParameters( );
|
|
|
|
}
|
|
|
|
void RenderDynamicWorld( )
|
|
{
|
|
UINT8 ubNumLevels;
|
|
UINT32 uiLevelFlags[ 10 ];
|
|
UINT16 sLevelIDs[ 10 ];
|
|
|
|
CalcRenderParameters( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, gsVIEWPORT_END_X, gsVIEWPORT_END_Y );
|
|
|
|
RestoreBackgroundRects();
|
|
|
|
if(!gfTagAnimatedTiles)
|
|
{
|
|
uiLevelFlags[0] = TILES_DYNAMIC_OBJECTS;
|
|
uiLevelFlags[1] = TILES_DYNAMIC_SHADOWS;
|
|
uiLevelFlags[2] = TILES_DYNAMIC_STRUCT_MERCS;
|
|
uiLevelFlags[3] = TILES_DYNAMIC_MERCS;
|
|
uiLevelFlags[4] = TILES_DYNAMIC_STRUCTURES;
|
|
uiLevelFlags[5] = TILES_DYNAMIC_HIGHMERCS;
|
|
uiLevelFlags[6] = TILES_DYNAMIC_ROOF;
|
|
uiLevelFlags[7] = TILES_DYNAMIC_ONROOF;
|
|
uiLevelFlags[8] = TILES_DYNAMIC_TOPMOST;
|
|
|
|
sLevelIDs[0] = RENDER_DYNAMIC_OBJECTS;
|
|
sLevelIDs[1] = RENDER_DYNAMIC_SHADOWS;
|
|
sLevelIDs[2] = RENDER_DYNAMIC_STRUCT_MERCS;
|
|
sLevelIDs[3] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[4] = RENDER_DYNAMIC_STRUCTS;
|
|
sLevelIDs[5] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[6] = RENDER_DYNAMIC_ROOF;
|
|
sLevelIDs[7] = RENDER_DYNAMIC_ONROOF;
|
|
sLevelIDs[8] = RENDER_DYNAMIC_TOPMOST;
|
|
|
|
ubNumLevels = 9;
|
|
}
|
|
else
|
|
{
|
|
gfTagAnimatedTiles=FALSE;
|
|
//uiLevelFlags[0] = TILES_DYNAMIC_LAND;
|
|
uiLevelFlags[0] = TILES_DYNAMIC_OBJECTS;
|
|
uiLevelFlags[1] = TILES_DYNAMIC_SHADOWS;
|
|
uiLevelFlags[2] = TILES_DYNAMIC_STRUCT_MERCS;
|
|
uiLevelFlags[3] = TILES_DYNAMIC_MERCS;
|
|
uiLevelFlags[4] = TILES_DYNAMIC_STRUCTURES;
|
|
uiLevelFlags[5] = TILES_DYNAMIC_HIGHMERCS;
|
|
uiLevelFlags[6] = TILES_DYNAMIC_ROOF;
|
|
uiLevelFlags[7] = TILES_DYNAMIC_ONROOF;
|
|
uiLevelFlags[8] = TILES_DYNAMIC_TOPMOST;
|
|
|
|
//sLevelIDs[0] = RENDER_DYNAMIC_LAND;
|
|
sLevelIDs[0] = RENDER_DYNAMIC_OBJECTS;
|
|
sLevelIDs[1] = RENDER_DYNAMIC_SHADOWS;
|
|
sLevelIDs[2] = RENDER_DYNAMIC_STRUCT_MERCS;
|
|
sLevelIDs[3] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[4] = RENDER_DYNAMIC_STRUCTS;
|
|
sLevelIDs[5] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[6] = RENDER_DYNAMIC_ROOF;
|
|
sLevelIDs[7] = RENDER_DYNAMIC_ONROOF;
|
|
sLevelIDs[8] = RENDER_DYNAMIC_TOPMOST;
|
|
|
|
ubNumLevels = 9;
|
|
}
|
|
|
|
RenderTiles(TILES_DIRTY, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, ubNumLevels, uiLevelFlags, sLevelIDs );
|
|
|
|
#ifdef JA2EDITOR
|
|
if( !gfEditMode && !gfAniEditMode )
|
|
#endif
|
|
{
|
|
RenderTacticalInterface( );
|
|
}
|
|
|
|
SaveBackgroundRects();
|
|
|
|
//uiLevelFlags[0] = TILES_DYNAMIC_LAND;
|
|
uiLevelFlags[0] = TILES_DYNAMIC_OBJECTS;
|
|
uiLevelFlags[1] = TILES_DYNAMIC_SHADOWS;
|
|
uiLevelFlags[2] = TILES_DYNAMIC_STRUCT_MERCS;
|
|
uiLevelFlags[3] = TILES_DYNAMIC_MERCS;
|
|
uiLevelFlags[4] = TILES_DYNAMIC_STRUCTURES;
|
|
|
|
//sLevelIDs[0] = RENDER_DYNAMIC_LAND;
|
|
sLevelIDs[0] = RENDER_DYNAMIC_OBJECTS;
|
|
sLevelIDs[1] = RENDER_DYNAMIC_SHADOWS;
|
|
sLevelIDs[2] = RENDER_DYNAMIC_STRUCT_MERCS;
|
|
sLevelIDs[3] = RENDER_DYNAMIC_MERCS;
|
|
sLevelIDs[4] = RENDER_DYNAMIC_STRUCTS;
|
|
|
|
RenderTiles( 0, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 5, uiLevelFlags , sLevelIDs );
|
|
|
|
|
|
uiLevelFlags[0] = TILES_DYNAMIC_ROOF;
|
|
uiLevelFlags[1] = TILES_DYNAMIC_HIGHMERCS;
|
|
uiLevelFlags[2] = TILES_DYNAMIC_ONROOF;
|
|
|
|
sLevelIDs[0] = RENDER_DYNAMIC_ROOF;
|
|
sLevelIDs[1] = RENDER_DYNAMIC_HIGHMERCS;
|
|
sLevelIDs[2] = RENDER_DYNAMIC_ONROOF;
|
|
|
|
RenderTiles(0 , gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 3, uiLevelFlags, sLevelIDs );
|
|
|
|
uiLevelFlags[0] = TILES_DYNAMIC_TOPMOST;
|
|
sLevelIDs[0] = RENDER_DYNAMIC_TOPMOST;
|
|
|
|
// ATE: check here for mouse over structs.....
|
|
RenderTiles( TILES_DYNAMIC_CHECKFOR_INT_TILE, gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS, 1, uiLevelFlags, sLevelIDs );
|
|
|
|
SumAddiviveLayerOptimization( );
|
|
|
|
ResetRenderParameters( );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN HandleScrollDirections( UINT32 ScrollFlags, INT16 sScrollXStep, INT16 sScrollYStep, INT16 *psTempRenderCenterX, INT16 *psTempRenderCenterY, BOOLEAN fCheckOnly )
|
|
{
|
|
BOOLEAN fAGoodMove = FALSE, fMovedPos = FALSE;
|
|
INT16 sTempX_W, sTempY_W;
|
|
BOOLEAN fUpOK, fLeftOK;
|
|
BOOLEAN fDownOK, fRightOK;
|
|
INT16 sTempRenderCenterX, sTempRenderCenterY;
|
|
|
|
sTempRenderCenterX = sTempRenderCenterY = 0;
|
|
|
|
// This checking sequence just validates the values!
|
|
if ( ScrollFlags & SCROLL_LEFT )
|
|
{
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
fMovedPos=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
if ( fMovedPos )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
}
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_LEFT, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_RIGHT )
|
|
{
|
|
FromScreenToCellCoordinates( sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fMovedPos=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
if ( fMovedPos )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
}
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_RIGHT, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_UP )
|
|
{
|
|
FromScreenToCellCoordinates( 0, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fMovedPos=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
if ( fMovedPos )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
}
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_UP, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_DOWN )
|
|
{
|
|
FromScreenToCellCoordinates( 0, sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fMovedPos=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
if ( fMovedPos )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
}
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_DOWN, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_UPLEFT )
|
|
{
|
|
// Check up
|
|
FromScreenToCellCoordinates( 0, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fUpOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
// Check left
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fLeftOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
|
|
if ( fLeftOK && fUpOK )
|
|
{
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_UPLEFT, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
else if ( fUpOK )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
|
|
FromScreenToCellCoordinates( 0, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_UP, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
else if ( fLeftOK )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_LEFT, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_UPRIGHT )
|
|
{
|
|
|
|
// Check up
|
|
FromScreenToCellCoordinates( 0, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fUpOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
// Check right
|
|
FromScreenToCellCoordinates( sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fRightOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
if ( fUpOK && fRightOK )
|
|
{
|
|
FromScreenToCellCoordinates( (INT16)sScrollXStep, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_UPRIGHT, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
else if ( fUpOK )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
|
|
FromScreenToCellCoordinates( 0, (INT16)-sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_UP, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
else if ( fRightOK )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
|
|
FromScreenToCellCoordinates( sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_RIGHT, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_DOWNLEFT )
|
|
{
|
|
// Check down......
|
|
FromScreenToCellCoordinates( 0, sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fDownOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
// Check left.....
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fLeftOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
if ( fLeftOK && fDownOK )
|
|
{
|
|
fAGoodMove = TRUE;
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, (INT16)sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_DOWNLEFT, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
else if ( fLeftOK )
|
|
{
|
|
FromScreenToCellCoordinates( (INT16)-sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_LEFT, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
else if ( fDownOK )
|
|
{
|
|
FromScreenToCellCoordinates( 0, sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground(SCROLL_DOWN, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ScrollFlags & SCROLL_DOWNRIGHT )
|
|
{
|
|
// Check right
|
|
FromScreenToCellCoordinates( sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fRightOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
// Check down
|
|
FromScreenToCellCoordinates( 0, sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fDownOK=ApplyScrolling( sTempRenderCenterX, sTempRenderCenterY, FALSE, fCheckOnly );
|
|
|
|
if ( fDownOK && fRightOK )
|
|
{
|
|
FromScreenToCellCoordinates( (INT16)sScrollXStep, (INT16)sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground( SCROLL_DOWNRIGHT, sScrollXStep, sScrollYStep );
|
|
}
|
|
|
|
}
|
|
else if ( fDownOK )
|
|
{
|
|
FromScreenToCellCoordinates( 0, sScrollYStep, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground( SCROLL_DOWN, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
else if ( fRightOK )
|
|
{
|
|
FromScreenToCellCoordinates( sScrollXStep, 0, &sTempX_W, &sTempY_W );
|
|
sTempRenderCenterX = gsRenderCenterX + sTempX_W;
|
|
sTempRenderCenterY = gsRenderCenterY + sTempY_W;
|
|
fAGoodMove = TRUE;
|
|
|
|
if ( !fCheckOnly )
|
|
{
|
|
ScrollBackground( SCROLL_RIGHT, sScrollXStep, sScrollYStep );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
( *psTempRenderCenterX ) = sTempRenderCenterX;
|
|
( *psTempRenderCenterY ) = sTempRenderCenterY;
|
|
|
|
|
|
return( fAGoodMove );
|
|
}
|
|
|
|
extern BOOLEAN gfNextRefreshFullScreen;
|
|
|
|
void ScrollWorld( )
|
|
{
|
|
UINT32 ScrollFlags = 0;
|
|
BOOLEAN fDoScroll = FALSE, fMovedPos=FALSE, fAGoodMove = FALSE;
|
|
INT16 sTempRenderCenterX, sTempRenderCenterY;
|
|
INT8 bDirection;
|
|
INT16 sScrollXStep=-1;
|
|
INT16 sScrollYStep=-1;
|
|
BOOLEAN fIgnoreInput = FALSE;
|
|
static UINT8 ubOldScrollSpeed = 0;
|
|
static BOOLEAN fFirstTimeInSlideToMode = TRUE;
|
|
|
|
|
|
if ( gfIgnoreScrollDueToCenterAdjust )
|
|
{
|
|
// gfIgnoreScrollDueToCenterAdjust = FALSE;
|
|
return;
|
|
}
|
|
|
|
if ( gfIgnoreScrolling == 1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( gfIgnoreScrolling == 2 )
|
|
{
|
|
fIgnoreInput = TRUE;
|
|
}
|
|
|
|
if ( gCurrentUIMode == LOCKUI_MODE )
|
|
{
|
|
fIgnoreInput = TRUE;
|
|
}
|
|
|
|
|
|
// If in editor, ignore scrolling if any of the shift keys pressed with arrow keys
|
|
if ( gfEditMode && ( _KeyDown(CTRL) || _KeyDown(ALT) ) )
|
|
return;
|
|
|
|
// Ignore if ALT DONW
|
|
if ( _KeyDown( ALT ) )
|
|
return;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
if ( gfIgnoreScrolling != 3 )
|
|
{
|
|
// Check for sliding
|
|
if ( gTacticalStatus.sSlideTarget != NOWHERE )
|
|
{
|
|
// Ignore all input...
|
|
// Check if we have reached out dest!
|
|
if ( fFirstTimeInSlideToMode )
|
|
{
|
|
ubOldScrollSpeed = gubCurScrollSpeedID;
|
|
fFirstTimeInSlideToMode = FALSE;
|
|
}
|
|
|
|
// Make faster!
|
|
//gubCurScrollSpeedID = 2;
|
|
|
|
ScrollFlags = 0;
|
|
fDoScroll = FALSE;
|
|
//
|
|
if ( SoldierLocationRelativeToScreen( gTacticalStatus.sSlideTarget, gTacticalStatus.sSlideReason, &bDirection, &ScrollFlags ) && GridNoOnVisibleWorldTile( gTacticalStatus.sSlideTarget ) )
|
|
{
|
|
ScrollFlags = gScrollDirectionFlags[ bDirection ];
|
|
fDoScroll = TRUE;
|
|
fIgnoreInput = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// We've stopped!
|
|
gTacticalStatus.sSlideTarget = NOWHERE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Restore old scroll speed
|
|
if ( !fFirstTimeInSlideToMode )
|
|
{
|
|
gubCurScrollSpeedID = ubOldScrollSpeed;
|
|
}
|
|
fFirstTimeInSlideToMode = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( !fIgnoreInput )
|
|
{
|
|
// Check keys
|
|
if ( _KeyDown( UPARROW ) )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_UP;
|
|
}
|
|
|
|
|
|
if ( _KeyDown( DNARROW ) )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_DOWN;
|
|
}
|
|
|
|
|
|
if ( _KeyDown( RIGHTARROW ) )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_RIGHT;
|
|
}
|
|
|
|
|
|
if ( _KeyDown( LEFTARROW ) )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_LEFT;
|
|
}
|
|
|
|
|
|
// Do mouse - PUT INTO A TIMER!
|
|
// Put a counter on starting from mouse, if we have not started already!
|
|
if ( !gfScrollInertia && gfScrollPending == FALSE )
|
|
{
|
|
if ( !COUNTERDONE( STARTSCROLL ) )
|
|
{
|
|
break;
|
|
}
|
|
RESETCOUNTER( STARTSCROLL );
|
|
|
|
}
|
|
|
|
if ( gusMouseYPos == 0 )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_UP;
|
|
}
|
|
|
|
|
|
if ( gusMouseYPos >= SCREEN_HEIGHT - 1 )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_DOWN;
|
|
}
|
|
|
|
|
|
if ( gusMouseXPos >= SCREEN_WIDTH - 1 )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_RIGHT;
|
|
}
|
|
|
|
|
|
if ( gusMouseXPos == 0 )
|
|
{
|
|
fDoScroll = TRUE;
|
|
ScrollFlags |= SCROLL_LEFT;
|
|
}
|
|
}
|
|
|
|
} while( FALSE );
|
|
|
|
|
|
if ( fDoScroll )
|
|
{
|
|
if ( gfDoSubtileScroll )
|
|
{
|
|
if ( gfScrollInertia > gubNewScrollIDSpeeds[ gubCurScrollSpeedID ] )
|
|
{
|
|
gubCurScrollSpeedID++;
|
|
|
|
if ( gubCurScrollSpeedID > gubScrollSpeedEndID )
|
|
{
|
|
gubCurScrollSpeedID = gubScrollSpeedEndID;
|
|
}
|
|
}
|
|
}
|
|
|
|
//if ( !gfDoVideoScroll )
|
|
//{
|
|
// gubCurScrollSpeedID = 4;
|
|
//}
|
|
|
|
|
|
// Adjust speed based on whether shift is down
|
|
if ( _KeyDown( SHIFT ) )
|
|
{
|
|
sScrollXStep = gubNewScrollXSpeeds[ gfDoVideoScroll ][ 3 ];
|
|
sScrollYStep = gubNewScrollYSpeeds[ gfDoVideoScroll ][ 3 ];
|
|
}
|
|
else
|
|
{
|
|
sScrollXStep = gubNewScrollXSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ];
|
|
sScrollYStep = gubNewScrollYSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ];
|
|
}
|
|
|
|
|
|
// Set diagonal flags!
|
|
if ( ( ScrollFlags & SCROLL_LEFT ) && ( ScrollFlags & SCROLL_UP ) )
|
|
{
|
|
ScrollFlags = SCROLL_UPLEFT;
|
|
}
|
|
if ( ( ScrollFlags & SCROLL_RIGHT ) && ( ScrollFlags & SCROLL_UP ) )
|
|
{
|
|
ScrollFlags = SCROLL_UPRIGHT;
|
|
}
|
|
if ( ( ScrollFlags & SCROLL_LEFT ) && ( ScrollFlags & SCROLL_DOWN ) )
|
|
{
|
|
ScrollFlags = SCROLL_DOWNLEFT;
|
|
}
|
|
if ( ( ScrollFlags & SCROLL_RIGHT ) && ( ScrollFlags & SCROLL_DOWN ) )
|
|
{
|
|
ScrollFlags = SCROLL_DOWNRIGHT;
|
|
}
|
|
|
|
fAGoodMove = HandleScrollDirections( ScrollFlags, sScrollXStep, sScrollYStep, &sTempRenderCenterX, &sTempRenderCenterY, TRUE );
|
|
}
|
|
|
|
// Has this been an OK scroll?
|
|
if ( fAGoodMove )
|
|
{
|
|
if ( COUNTERDONE( NEXTSCROLL ) )
|
|
{
|
|
RESETCOUNTER( NEXTSCROLL );
|
|
|
|
// Are we starting a new scroll?
|
|
if ( gfScrollInertia == 0 && gfScrollPending == FALSE )
|
|
{
|
|
// We are starting to scroll - setup scroll pending
|
|
gfScrollPending = TRUE;
|
|
|
|
// Remove any interface stuff
|
|
ClearInterface( );
|
|
|
|
// Return so that next frame things will be erased!
|
|
return;
|
|
}
|
|
|
|
// If here, set scroll pending to false
|
|
gfScrollPending = FALSE;
|
|
|
|
|
|
// INcrement scroll intertia
|
|
gfScrollInertia++;
|
|
|
|
// Now we actually begin our scrolling
|
|
HandleScrollDirections( ScrollFlags, sScrollXStep, sScrollYStep, &sTempRenderCenterX, &sTempRenderCenterY, FALSE );
|
|
|
|
if( gfNextRefreshFullScreen ) SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ATE: Also if scroll pending never got to scroll....
|
|
if ( gfScrollPending == TRUE )
|
|
{
|
|
// Do a complete rebuild!
|
|
gfScrollPending = FALSE;
|
|
|
|
// Restore Interface!
|
|
RestoreInterface( );
|
|
|
|
// Delete Topmost blitters saved areas
|
|
DeleteVideoOverlaysArea( );
|
|
|
|
}
|
|
|
|
// Check if we have just stopped scrolling!
|
|
if ( gfScrollInertia != FALSE )
|
|
{
|
|
SetRenderFlags( RENDER_FLAG_FULL | RENDER_FLAG_CHECKZ );
|
|
|
|
// Restore Interface!
|
|
RestoreInterface( );
|
|
|
|
// Delete Topmost blitters saved areas
|
|
DeleteVideoOverlaysArea( );
|
|
|
|
}
|
|
|
|
gfScrollInertia = FALSE;
|
|
gfScrollPending = FALSE;
|
|
|
|
if ( gfDoSubtileScroll )
|
|
{
|
|
gubCurScrollSpeedID = gubScrollSpeedStartID;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* Initialization
|
|
*
|
|
* any questions? joker
|
|
*/
|
|
|
|
void InitializeViewPort()
|
|
{
|
|
gsVIEWPORT_START_X = 0;
|
|
gsVIEWPORT_START_Y = 0;
|
|
gsVIEWPORT_WINDOW_START_Y = 0;
|
|
gsVIEWPORT_WINDOW_END_Y = INTERFACE_START_Y;
|
|
gsVIEWPORT_END_X = SCREEN_WIDTH;
|
|
gsVIEWPORT_END_Y = INTERFACE_START_Y;
|
|
|
|
gClippingRect.iLeft = 0;
|
|
gClippingRect.iTop = 0;
|
|
gClippingRect.iRight = SCREEN_WIDTH;
|
|
gClippingRect.iBottom = SCREEN_HEIGHT - INTERFACE_HEIGHT;
|
|
}
|
|
|
|
void InitRenderParams( UINT8 ubRestrictionID )
|
|
{
|
|
INT16 gsTilesX, gsTilesY;
|
|
UINT32 cnt, cnt2;
|
|
DOUBLE dWorldX, dWorldY;
|
|
|
|
switch( ubRestrictionID )
|
|
{
|
|
case 0: //Default!
|
|
|
|
gTopLeftWorldLimitX = CELL_X_SIZE;
|
|
gTopLeftWorldLimitY = ( WORLD_ROWS / 2 ) * CELL_X_SIZE;
|
|
|
|
gTopRightWorldLimitX = ( WORLD_COLS / 2 ) * CELL_Y_SIZE;
|
|
gTopRightWorldLimitY = CELL_X_SIZE;
|
|
|
|
gBottomLeftWorldLimitX = ( ( WORLD_COLS / 2 ) * CELL_Y_SIZE );
|
|
gBottomLeftWorldLimitY = ( WORLD_ROWS * CELL_Y_SIZE );
|
|
|
|
gBottomRightWorldLimitX = ( WORLD_COLS * CELL_Y_SIZE );
|
|
gBottomRightWorldLimitY = ( ( WORLD_ROWS / 2 ) * CELL_X_SIZE );
|
|
break;
|
|
|
|
case 1: // BAEMENT LEVEL 1
|
|
|
|
gTopLeftWorldLimitX = ( 3 * WORLD_ROWS / 10 ) * CELL_X_SIZE;
|
|
gTopLeftWorldLimitY = ( WORLD_ROWS / 2 ) * CELL_X_SIZE;
|
|
|
|
gTopRightWorldLimitX = ( WORLD_ROWS / 2 ) * CELL_X_SIZE;
|
|
gTopRightWorldLimitY = ( 3 * WORLD_COLS / 10 ) * CELL_X_SIZE;
|
|
|
|
gBottomLeftWorldLimitX = ( WORLD_ROWS / 2 ) * CELL_X_SIZE;
|
|
gBottomLeftWorldLimitY = ( 7 * WORLD_COLS / 10 ) * CELL_X_SIZE;
|
|
|
|
gBottomRightWorldLimitX = ( 7 * WORLD_ROWS / 10 ) * CELL_X_SIZE;
|
|
gBottomRightWorldLimitY = ( WORLD_ROWS / 2 ) * CELL_X_SIZE;
|
|
break;
|
|
|
|
}
|
|
|
|
gCenterWorldX = ( WORLD_ROWS ) / 2 * CELL_X_SIZE;
|
|
gCenterWorldY = ( WORLD_COLS ) / 2 * CELL_Y_SIZE;
|
|
|
|
// Convert Bounding box into screen coords
|
|
FromCellToScreenCoordinates( gTopLeftWorldLimitX, gTopLeftWorldLimitY, &gsTLX, &gsTLY );
|
|
FromCellToScreenCoordinates( gTopRightWorldLimitX, gTopRightWorldLimitY, &gsTRX, &gsTRY );
|
|
FromCellToScreenCoordinates( gBottomLeftWorldLimitX, gBottomLeftWorldLimitY, &gsBLX, &gsBLY );
|
|
FromCellToScreenCoordinates( gBottomRightWorldLimitX, gBottomRightWorldLimitY, &gsBRX, &gsBRY );
|
|
FromCellToScreenCoordinates( gCenterWorldX , gCenterWorldY, &gsCX, &gsCY );
|
|
|
|
// Adjust for interface height tabbing!
|
|
gsTLY += ROOF_LEVEL_HEIGHT;
|
|
gsTRY += ROOF_LEVEL_HEIGHT;
|
|
gsCY += ( ROOF_LEVEL_HEIGHT / 2 );
|
|
|
|
// Take these spaning distances and determine # tiles spaning
|
|
gsTilesX = ( gsTRX - gsTLX ) / WORLD_TILE_X;
|
|
gsTilesY = ( gsBRY - gsTRY ) / WORLD_TILE_Y;
|
|
|
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_0, String("World Screen Width %d Height %d", ( gsTRX - gsTLX ), ( gsBRY - gsTRY )));
|
|
|
|
|
|
// Determine scale factors
|
|
// First scale world screen coords for VIEWPORT ratio
|
|
dWorldX = (DOUBLE)( gsTRX - gsTLX );
|
|
dWorldY = (DOUBLE)( gsBRY - gsTRY );
|
|
|
|
gdScaleX = (DOUBLE)RADAR_WINDOW_WIDTH / dWorldX;
|
|
gdScaleY = (DOUBLE)RADAR_WINDOW_HEIGHT / dWorldY;
|
|
|
|
for ( cnt = 0, cnt2 = 0; cnt2 < NUM_ITEM_CYCLE_COLORS; cnt+=3, cnt2++ )
|
|
{
|
|
us16BPPItemCycleWhiteColors[ cnt2 ] = Get16BPPColor( FROMRGB( ubRGBItemCycleWhiteColors[ cnt ], ubRGBItemCycleWhiteColors[ cnt + 1 ], ubRGBItemCycleWhiteColors[ cnt + 2] ) );
|
|
us16BPPItemCycleRedColors[ cnt2 ] = Get16BPPColor( FROMRGB( ubRGBItemCycleRedColors[ cnt ], ubRGBItemCycleRedColors[ cnt + 1 ], ubRGBItemCycleRedColors[ cnt + 2] ) );
|
|
us16BPPItemCycleYellowColors[ cnt2 ] = Get16BPPColor( FROMRGB( ubRGBItemCycleYellowColors[ cnt ], ubRGBItemCycleYellowColors[ cnt + 1 ], ubRGBItemCycleYellowColors[ cnt + 2] ) );
|
|
}
|
|
|
|
gsLobOutline = Get16BPPColor( FROMRGB( 10, 200, 10 ) );
|
|
gsThrowOutline = Get16BPPColor( FROMRGB( 253, 212, 10 ) );
|
|
gsGiveOutline = Get16BPPColor( FROMRGB( 253, 0, 0 ) );
|
|
|
|
gusNormalItemOutlineColor = Get16BPPColor( FROMRGB( 255, 255, 255 ) );
|
|
gusYellowItemOutlineColor = Get16BPPColor( FROMRGB( 255, 255, 0 ) );
|
|
|
|
// NOW GET DISTANCE SPANNING WORLD LIMITS IN WORLD COORDS
|
|
//FromScreenToCellCoordinates( ( gTopRightWorldLimitX - gTopLeftWorldLimitX ), ( gTopRightWorldLimitY - gTopLeftWorldLimitY ), &gsWorldSpanX, &gsWorldSpanY );
|
|
|
|
// CALCULATE 16BPP COLORS FOR ITEMS
|
|
|
|
}
|
|
|
|
// WANNE: Scrolling: Only scroll, if the map is larger than the radar map
|
|
// For example: Do not allow scrolling in Rebel Basement.
|
|
// Appy? HEahehahehahehae.....
|
|
BOOLEAN ApplyScrolling( INT16 sTempRenderCenterX, INT16 sTempRenderCenterY, BOOLEAN fForceAdjust, BOOLEAN fCheckOnly )
|
|
{
|
|
BOOLEAN fScrollGood = FALSE;
|
|
BOOLEAN fOutLeft = FALSE;
|
|
BOOLEAN fOutRight = FALSE;
|
|
BOOLEAN fOutTop = FALSE;
|
|
BOOLEAN fOutBottom = FALSE;
|
|
|
|
|
|
double dOpp, dAdj, dAngle;
|
|
|
|
INT16 sTopLeftWorldX, sTopLeftWorldY;
|
|
INT16 sTopRightWorldX, sTopRightWorldY;
|
|
INT16 sBottomLeftWorldX, sBottomLeftWorldY;
|
|
INT16 sBottomRightWorldX, sBottomRightWorldY;
|
|
|
|
INT16 sTempPosX_W, sTempPosY_W;
|
|
|
|
|
|
// For debug text for all 4 angles
|
|
double at1, at2, at3, at4;
|
|
|
|
INT16 sX_S, sY_S;
|
|
INT16 sScreenCenterX, sScreenCenterY;
|
|
INT16 sDistToCenterY, sDistToCenterX;
|
|
INT16 sNewScreenX, sNewScreenY;
|
|
INT16 sMult;
|
|
|
|
// WANNE:
|
|
INT16 sRadarTLX, sRadarTLY;
|
|
INT16 sRadarBRX, sRadarBRY;
|
|
INT16 sRadarCX, sRadarCY;
|
|
INT16 sHeight, sWidth, sX, sY;
|
|
INT16 gsRadarY;
|
|
BOOLEAN fAllowScrollingHorizontal = FALSE;
|
|
BOOLEAN fAllowScrollingVertical = FALSE;
|
|
|
|
|
|
//Makesure it's a multiple of 5
|
|
sMult = sTempRenderCenterX / CELL_X_SIZE;
|
|
sTempRenderCenterX = ( sMult * CELL_X_SIZE ) + ( CELL_X_SIZE / 2 );
|
|
|
|
//Makesure it's a multiple of 5
|
|
sMult = sTempRenderCenterY / CELL_Y_SIZE;
|
|
sTempRenderCenterY = ( sMult * CELL_Y_SIZE ) + ( CELL_Y_SIZE / 2 );
|
|
|
|
|
|
// Find the diustance from render center to true world center
|
|
sDistToCenterX = sTempRenderCenterX - gCenterWorldX;
|
|
sDistToCenterY = sTempRenderCenterY - gCenterWorldY;
|
|
|
|
// From render center in world coords, convert to render center in "screen" coords
|
|
FromCellToScreenCoordinates( sDistToCenterX , sDistToCenterY, &sScreenCenterX, &sScreenCenterY );
|
|
|
|
// Subtract screen center
|
|
sScreenCenterX += gsCX;
|
|
sScreenCenterY += gsCY;
|
|
|
|
// Adjust for offset position on screen
|
|
sScreenCenterX -= 0;
|
|
sScreenCenterY -= 10;
|
|
|
|
|
|
// Get corners in screen coords
|
|
// TOP LEFT
|
|
sX_S = ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2;
|
|
sY_S = ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2;
|
|
|
|
sTopLeftWorldX = sScreenCenterX - sX_S;
|
|
sTopLeftWorldY = sScreenCenterY - sY_S;
|
|
|
|
sTopRightWorldX = sScreenCenterX + sX_S;
|
|
sTopRightWorldY = sScreenCenterY - sY_S;
|
|
|
|
sBottomLeftWorldX = sScreenCenterX - sX_S;
|
|
sBottomLeftWorldY = sScreenCenterY + sY_S;
|
|
|
|
sBottomRightWorldX = sScreenCenterX + sX_S;
|
|
sBottomRightWorldY = sScreenCenterY + sY_S;
|
|
|
|
|
|
// WANNE: Scrolling bugfix, if we are talking in a small tactical map (e.g: Rebel Basement) in high resolution (1024x768)[2007-05-14]
|
|
// Determine radar coordinates
|
|
sRadarCX = (INT16)( gsCX * gdScaleX );
|
|
sRadarCY = (INT16)( gsCY * gdScaleY );
|
|
|
|
if( guiCurrentScreen == MAP_SCREEN )
|
|
{
|
|
gsRadarY = RADAR_WINDOW_STRAT_Y;
|
|
}
|
|
else if ( gsCurInterfacePanel == SM_PANEL )
|
|
{
|
|
gsRadarY = RADAR_WINDOW_TM_Y;
|
|
}
|
|
else
|
|
{
|
|
gsRadarY = RADAR_WINDOW_TM_Y;
|
|
}
|
|
|
|
|
|
sWidth = ( RADAR_WINDOW_WIDTH );
|
|
sHeight = ( RADAR_WINDOW_HEIGHT );
|
|
sX = RADAR_WINDOW_X;
|
|
sY = gsRadarY;
|
|
|
|
|
|
sRadarTLX = (INT16)( ( sTopLeftWorldX * gdScaleX ) - sRadarCX + sX + ( sWidth /2 ) );
|
|
sRadarTLY = (INT16)( ( sTopLeftWorldY * gdScaleY ) - sRadarCY + gsRadarY + ( sHeight /2 ) );
|
|
sRadarBRX = (INT16)( ( sBottomRightWorldX * gdScaleX ) - sRadarCX + sX + ( sWidth /2 ) );
|
|
sRadarBRY = (INT16)( ( sBottomRightWorldY * gdScaleY ) - sRadarCY + gsRadarY + ( sHeight /2 ) );
|
|
|
|
// WANNE: Scrolling bugfix, if we are talking in a small tactical map (e.g: Rebel Basement) in high resolution (1024x768)[2007-05-14]
|
|
if ((sRadarBRX - sRadarTLX) <= RADAR_WINDOW_WIDTH)
|
|
{
|
|
fAllowScrollingHorizontal = TRUE;
|
|
}
|
|
|
|
if ((sRadarBRY - sRadarTLY) <= RADAR_WINDOW_HEIGHT)
|
|
{
|
|
fAllowScrollingVertical = TRUE;
|
|
}
|
|
|
|
if ((fAllowScrollingHorizontal == FALSE || fAllowScrollingVertical == FALSE) && (gfDialogControl == TRUE))
|
|
{
|
|
gfDialogControl = FALSE;
|
|
return (FALSE);
|
|
}
|
|
|
|
// WANNE: Scrolling bugfix for small maps in high resolution (eg: Rebel Basement)
|
|
//if ((fAllowScrollingHorizontal || fAllowScrollingVertical) && gfDialogControl)
|
|
//{
|
|
|
|
// Get angles
|
|
// TOP LEFT CORNER FIRST
|
|
dOpp = sTopLeftWorldY - gsTLY;
|
|
dAdj = sTopLeftWorldX - gsTLX;
|
|
|
|
dAngle = (double)atan2( dAdj, dOpp );
|
|
at1 = dAngle * 180 / PI;
|
|
|
|
if ( dAngle < 0 )
|
|
{
|
|
fOutLeft = TRUE;
|
|
}
|
|
else if ( dAngle > PI/2 )
|
|
{
|
|
fOutTop = TRUE;
|
|
}
|
|
|
|
// TOP RIGHT CORNER
|
|
dOpp = sTopRightWorldY - gsTRY;
|
|
dAdj = gsTRX - sTopRightWorldX;
|
|
|
|
dAngle = (double)atan2( dAdj, dOpp );
|
|
at2 = dAngle * 180 / PI;
|
|
|
|
if ( dAngle < 0 )
|
|
{
|
|
fOutRight = TRUE;
|
|
}
|
|
else if ( dAngle > PI/2 )
|
|
{
|
|
fOutTop = TRUE;
|
|
}
|
|
|
|
|
|
// BOTTOM LEFT CORNER
|
|
dOpp = gsBLY - sBottomLeftWorldY;
|
|
dAdj = sBottomLeftWorldX - gsBLX;
|
|
|
|
dAngle = (double)atan2( dAdj, dOpp );
|
|
at3 = dAngle * 180 / PI;
|
|
|
|
if ( dAngle < 0 )
|
|
{
|
|
fOutLeft = TRUE;
|
|
}
|
|
else if ( dAngle > PI/2 )
|
|
{
|
|
fOutBottom = TRUE;
|
|
}
|
|
|
|
// BOTTOM RIGHT CORNER
|
|
dOpp = gsBRY - sBottomRightWorldY;
|
|
dAdj = gsBRX - sBottomRightWorldX;
|
|
|
|
dAngle = (double)atan2( dAdj, dOpp );
|
|
at4 = dAngle * 180 / PI;
|
|
|
|
if ( dAngle < 0 )
|
|
{
|
|
fOutRight = TRUE;
|
|
}
|
|
else if ( dAngle > PI/2 )
|
|
{
|
|
fOutBottom = TRUE;
|
|
}
|
|
|
|
sprintf( gDebugStr, "Angles: %d %d %d %d", (int)at1, (int)at2, (int)at3, (int)at4 );
|
|
|
|
if ( !fOutRight && !fOutLeft && !fOutTop && !fOutBottom )
|
|
{
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
// If in editor, anything goes
|
|
if ( gfEditMode && _KeyDown( SHIFT ) )
|
|
{
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
// Reset some UI flags
|
|
gfUIShowExitEast = FALSE;
|
|
gfUIShowExitWest = FALSE;
|
|
gfUIShowExitNorth = FALSE;
|
|
gfUIShowExitSouth = FALSE;
|
|
|
|
|
|
if ( !fScrollGood )
|
|
{
|
|
// Force adjustment, if true
|
|
if ( fForceAdjust )
|
|
{
|
|
if ( fOutTop )
|
|
{
|
|
// WANNE: Test
|
|
// Adjust screen coordinates on the Y!
|
|
CorrectRenderCenter( sScreenCenterX, (INT16)(gsTLY + sY_S ), &sNewScreenX, &sNewScreenY );
|
|
FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W );
|
|
|
|
sTempRenderCenterX = sTempPosX_W;
|
|
sTempRenderCenterY = sTempPosY_W;
|
|
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
if ( fOutBottom )
|
|
{
|
|
// OK, Ajust this since we get rounding errors in our two different calculations.
|
|
CorrectRenderCenter( sScreenCenterX, (INT16)(gsBLY - sY_S - 50 ), &sNewScreenX, &sNewScreenY );
|
|
FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W );
|
|
|
|
sTempRenderCenterX = sTempPosX_W;
|
|
sTempRenderCenterY = sTempPosY_W;
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
if ( fOutLeft )
|
|
{
|
|
CorrectRenderCenter( (INT16)( gsTLX + sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY );
|
|
FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W );
|
|
|
|
sTempRenderCenterX = sTempPosX_W;
|
|
sTempRenderCenterY = sTempPosY_W;
|
|
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
if ( fOutRight )
|
|
{
|
|
CorrectRenderCenter( (INT16)( gsTRX - sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY );
|
|
FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W );
|
|
|
|
sTempRenderCenterX = sTempPosX_W;
|
|
sTempRenderCenterY = sTempPosY_W;
|
|
fScrollGood = TRUE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( fOutRight )
|
|
{
|
|
// Check where our cursor is!
|
|
if ( gusMouseXPos >= SCREEN_WIDTH - 1 )
|
|
{
|
|
gfUIShowExitEast = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( fOutLeft )
|
|
{
|
|
// Check where our cursor is!
|
|
if ( gusMouseXPos == 0 )
|
|
{
|
|
gfUIShowExitWest = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( fOutTop )
|
|
{
|
|
// Check where our cursor is!
|
|
if ( gusMouseYPos == 0 )
|
|
{
|
|
gfUIShowExitNorth = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( fOutBottom )
|
|
{
|
|
// Check where our cursor is!
|
|
if ( gusMouseYPos >= SCREEN_HEIGHT - 1 )
|
|
{
|
|
gfUIShowExitSouth = TRUE;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if ( fScrollGood )
|
|
{
|
|
if ( !fCheckOnly )
|
|
{
|
|
sprintf( gDebugStr, "Center: %d %d ", (int)gsRenderCenterX, (int)gsRenderCenterY );
|
|
|
|
//Makesure it's a multiple of 5
|
|
sMult = sTempRenderCenterX / CELL_X_SIZE;
|
|
|
|
gsRenderCenterX = ( sMult * CELL_X_SIZE ) + ( CELL_X_SIZE / 2 );
|
|
|
|
//Makesure it's a multiple of 5
|
|
sMult = sTempRenderCenterY / CELL_Y_SIZE;
|
|
|
|
gsRenderCenterY = ( sMult * CELL_Y_SIZE ) + ( CELL_Y_SIZE / 2 );
|
|
|
|
//gsRenderCenterX = sTempRenderCenterX;
|
|
//gsRenderCenterY = sTempRenderCenterY;
|
|
|
|
|
|
gsTopLeftWorldX = sTopLeftWorldX - gsTLX;
|
|
gsTopRightWorldX = sTopRightWorldX - gsTLX;
|
|
gsBottomLeftWorldX = sBottomLeftWorldX - gsTLX;
|
|
gsBottomRightWorldX = sBottomRightWorldX - gsTLX;
|
|
|
|
gsTopLeftWorldY = sTopLeftWorldY - gsTLY;
|
|
gsTopRightWorldY = sTopRightWorldY - gsTLY;
|
|
gsBottomLeftWorldY = sBottomLeftWorldY - gsTLY;
|
|
gsBottomRightWorldY = sBottomRightWorldY - gsTLY;
|
|
|
|
SetPositionSndsVolumeAndPanning( );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
//}
|
|
|
|
//return ( FALSE );
|
|
}
|
|
|
|
|
|
void ClearMarkedTiles(void)
|
|
{
|
|
UINT32 uiCount;
|
|
|
|
for(uiCount=0; uiCount < WORLD_MAX; uiCount++)
|
|
gpWorldLevelData[uiCount].uiFlags&=(~MAPELEMENT_REDRAW);
|
|
|
|
}
|
|
|
|
// @@ATECLIP TO WORLD!
|
|
void InvalidateWorldRedundencyRadius(INT16 sX, INT16 sY, INT16 sRadius)
|
|
{
|
|
INT16 sCountX, sCountY;
|
|
UINT32 uiTile;
|
|
|
|
SetRenderFlags( RENDER_FLAG_CHECKZ );
|
|
|
|
for(sCountY=sY-sRadius; sCountY < (sY+sRadius+2); sCountY++)
|
|
{
|
|
for(sCountX=sX-sRadius; sCountX < (sX+sRadius+2); sCountX++)
|
|
{
|
|
uiTile=FASTMAPROWCOLTOPOS(sCountY, sCountX);
|
|
|
|
gpWorldLevelData[uiTile].uiFlags |= MAPELEMENT_REEVALUATE_REDUNDENCY;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void InvalidateWorldRedundency( )
|
|
{
|
|
UINT32 uiCount;
|
|
|
|
SetRenderFlags( RENDER_FLAG_CHECKZ );
|
|
|
|
for(uiCount=0; uiCount < WORLD_MAX; uiCount++)
|
|
gpWorldLevelData[uiCount].uiFlags |= MAPELEMENT_REEVALUATE_REDUNDENCY;
|
|
|
|
}
|
|
|
|
#define Z_STRIP_DELTA_Y ( Z_SUBLAYERS * 10 )
|
|
|
|
/**********************************************************************************************
|
|
Blt8BPPDataTo16BPPBufferTransZIncClip
|
|
|
|
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
|
|
buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
|
|
pixel's Z level is below that of the current pixel, it is written on, and the Z value is
|
|
updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
|
|
must be the same dimensions (including Pitch) as the destination.
|
|
|
|
**********************************************************************************************/
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
|
|
{
|
|
UINT16 *p16BPPPalette;
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth, Unblitted;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
|
|
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
|
|
UINT16 usZLevel, usZStartLevel, usZColsToGo, usZStartIndex, usCount, usZIndex, usZStartCols;
|
|
INT8 *pZArray;
|
|
ZStripInfo *pZInfo;
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
if(clipregion==NULL)
|
|
{
|
|
ClipX1=ClippingRect.iLeft;
|
|
ClipY1=ClippingRect.iTop;
|
|
ClipX2=ClippingRect.iRight;
|
|
ClipY2=ClippingRect.iBottom;
|
|
}
|
|
else
|
|
{
|
|
ClipX1=clipregion->iLeft;
|
|
ClipY1=clipregion->iTop;
|
|
ClipX2=clipregion->iRight;
|
|
ClipY2=clipregion->iBottom;
|
|
}
|
|
|
|
// Calculate rows hanging off each side of the screen
|
|
LeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
|
|
RightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
|
|
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
|
|
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
|
|
|
|
// calculate the remaining rows and columns to blit
|
|
BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
|
|
BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
|
|
|
|
// check if whole thing is clipped
|
|
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
|
|
return(TRUE);
|
|
|
|
// check if whole thing is clipped
|
|
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
|
|
return(TRUE);
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
p16BPPPalette = hSrcVObject->pShadeCurrent;
|
|
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
|
|
|
|
if(hSrcVObject->ppZStripInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
// setup for the z-column blitting stuff
|
|
pZInfo=hSrcVObject->ppZStripInfo[usIndex];
|
|
if(pZInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
|
|
usZStartLevel=(UINT16)((INT16)usZValue+((INT16)pZInfo->bInitialZChange*Z_STRIP_DELTA_Y));
|
|
// set to odd number of pixels for first column
|
|
|
|
if(LeftSkip > pZInfo->ubFirstZStripWidth)
|
|
{
|
|
usZStartCols=(LeftSkip - pZInfo->ubFirstZStripWidth);
|
|
usZStartCols=20-(usZStartCols%20);
|
|
}
|
|
else if(LeftSkip < pZInfo->ubFirstZStripWidth)
|
|
usZStartCols=(UINT16)(pZInfo->ubFirstZStripWidth - LeftSkip);
|
|
else
|
|
usZStartCols=20;
|
|
|
|
usZColsToGo=usZStartCols;
|
|
|
|
pZArray=pZInfo->pbZChange;
|
|
|
|
if(LeftSkip >= pZInfo->ubFirstZStripWidth)
|
|
{
|
|
// Index into array after doing left clipping
|
|
usZStartIndex=1 + ((LeftSkip-pZInfo->ubFirstZStripWidth)/20);
|
|
|
|
//calculates the Z-value after left-side clipping
|
|
if(usZStartIndex)
|
|
{
|
|
for(usCount=0; usCount < usZStartIndex; usCount++)
|
|
{
|
|
switch(pZArray[usCount])
|
|
{
|
|
case -1: usZStartLevel-=Z_STRIP_DELTA_Y;
|
|
break;
|
|
case 0: //no change
|
|
break;
|
|
case 1: usZStartLevel+=Z_STRIP_DELTA_Y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
usZStartIndex=0;
|
|
|
|
usZLevel=usZStartLevel;
|
|
usZIndex=usZStartIndex;
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
cmp TopSkip, 0 // check for nothing clipped on top
|
|
je LeftSkipSetup
|
|
|
|
|
|
// Skips the number of lines clipped at the top
|
|
TopSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js TopSkipLoop
|
|
jz TSEndLine
|
|
|
|
add esi, ecx
|
|
jmp TopSkipLoop
|
|
|
|
TSEndLine:
|
|
dec TopSkip
|
|
jnz TopSkipLoop
|
|
|
|
|
|
// Start of line loop
|
|
|
|
// Skips the pixels hanging outside the left-side boundry
|
|
LeftSkipSetup:
|
|
|
|
mov Unblitted, 0 // Unblitted counts any pixels left from a run
|
|
mov eax, LeftSkip // after we have skipped enough left-side pixels
|
|
mov LSCount, eax // LSCount counts how many pixels skipped so far
|
|
or eax, eax
|
|
jz BlitLineSetup // check for nothing to skip
|
|
|
|
LeftSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
|
|
or cl, cl
|
|
js LSTrans
|
|
|
|
cmp ecx, LSCount
|
|
je LSSkip2 // if equal, skip whole, and start blit with new run
|
|
jb LSSkip1 // if less, skip whole thing
|
|
|
|
add esi, LSCount // skip partial run, jump into normal loop for rest
|
|
sub ecx, LSCount
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitNTL1 // *** jumps into non-transparent blit loop
|
|
|
|
LSSkip2:
|
|
add esi, ecx // skip whole run, and start blit with new run
|
|
jmp BlitLineSetup
|
|
|
|
|
|
LSSkip1:
|
|
add esi, ecx // skip whole run, continue skipping
|
|
sub LSCount, ecx
|
|
jmp LeftSkipLoop
|
|
|
|
|
|
LSTrans:
|
|
and ecx, 07fH
|
|
cmp ecx, LSCount
|
|
je BlitLineSetup // if equal, skip whole, and start blit with new run
|
|
jb LSTrans1 // if less, skip whole thing
|
|
|
|
sub ecx, LSCount // skip partial run, jump into normal loop for rest
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitTransparent // *** jumps into transparent blit loop
|
|
|
|
|
|
LSTrans1:
|
|
sub LSCount, ecx // skip whole run, continue skipping
|
|
jmp LeftSkipLoop
|
|
|
|
//-------------------------------------------------
|
|
// setup for beginning of line
|
|
|
|
BlitLineSetup:
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
|
|
BlitDispatch:
|
|
|
|
cmp LSCount, 0 // Check to see if we're done blitting
|
|
je RightSkipLoop
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz RSLoop2
|
|
|
|
//--------------------------------
|
|
// blitting non-transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitNTL1:
|
|
mov ax, [ebx] // check z-level of pixel
|
|
cmp ax, usZLevel
|
|
jae BlitNTL2
|
|
|
|
mov ax, usZLevel // update z-level of pixel
|
|
mov [ebx], ax
|
|
|
|
xor eax, eax
|
|
mov al, [esi] // copy pixel
|
|
mov ax, [edx+eax*2]
|
|
mov [edi], ax
|
|
|
|
BlitNTL2:
|
|
inc esi
|
|
add edi, 2
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitNTL6
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitNTL5 // dir = 0 no change
|
|
js BlitNTL4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitNTL5
|
|
|
|
BlitNTL4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitNTL5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitNTL6:
|
|
dec LSCount // decrement pixel length to blit
|
|
jz RightSkipLoop // done blitting the visible line
|
|
|
|
dec ecx
|
|
jnz BlitNTL1 // continue current run
|
|
|
|
jmp BlitDispatch // done current run, go for another
|
|
|
|
|
|
//----------------------------
|
|
// skipping transparent pixels
|
|
|
|
BlitTransparent: // skip transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitTrans2:
|
|
|
|
add edi, 2 // move up the destination pointer
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitTrans1
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitTrans5 // dir = 0 no change
|
|
js BlitTrans4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitTrans5
|
|
|
|
BlitTrans4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitTrans5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitTrans1:
|
|
|
|
dec LSCount // decrement the pixels to blit
|
|
jz RightSkipLoop // done the line
|
|
|
|
dec ecx
|
|
jnz BlitTrans2
|
|
|
|
jmp BlitDispatch
|
|
|
|
//---------------------------------------------
|
|
// Scans the ETRLE until it finds an EOL marker
|
|
|
|
RightSkipLoop:
|
|
|
|
|
|
RSLoop1:
|
|
mov al, [esi]
|
|
inc esi
|
|
or al, al
|
|
jnz RSLoop1
|
|
|
|
RSLoop2:
|
|
|
|
dec BlitHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
|
|
// reset all the z-level stuff for a new line
|
|
|
|
mov ax, usZStartLevel
|
|
mov usZLevel, ax
|
|
mov ax, usZStartIndex
|
|
mov usZIndex, ax
|
|
mov ax, usZStartCols
|
|
mov usZColsToGo, ax
|
|
|
|
|
|
jmp LeftSkipSetup
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/**********************************************************************************************
|
|
Blt8BPPDataTo16BPPBufferTransZIncClipSaveZBurnsThrough
|
|
|
|
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
|
|
buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
|
|
pixel's Z level is below that of the current pixel, it is written on, and the Z value is
|
|
updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
|
|
must be the same dimensions (including Pitch) as the destination.
|
|
|
|
**********************************************************************************************/
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncClipZSameZBurnsThrough( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 usZStripIndex )
|
|
{
|
|
UINT16 *p16BPPPalette;
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth, Unblitted;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
|
|
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
|
|
UINT16 usZLevel, usZStartLevel, usZColsToGo, usZStartIndex, usCount, usZIndex, usZStartCols;
|
|
INT8 *pZArray;
|
|
ZStripInfo *pZInfo;
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
if(clipregion==NULL)
|
|
{
|
|
ClipX1=ClippingRect.iLeft;
|
|
ClipY1=ClippingRect.iTop;
|
|
ClipX2=ClippingRect.iRight;
|
|
ClipY2=ClippingRect.iBottom;
|
|
}
|
|
else
|
|
{
|
|
ClipX1=clipregion->iLeft;
|
|
ClipY1=clipregion->iTop;
|
|
ClipX2=clipregion->iRight;
|
|
ClipY2=clipregion->iBottom;
|
|
}
|
|
|
|
// Calculate rows hanging off each side of the screen
|
|
LeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
|
|
RightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
|
|
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
|
|
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
|
|
|
|
// calculate the remaining rows and columns to blit
|
|
BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
|
|
BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
|
|
|
|
// check if whole thing is clipped
|
|
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
|
|
return(TRUE);
|
|
|
|
// check if whole thing is clipped
|
|
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
|
|
return(TRUE);
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
p16BPPPalette = hSrcVObject->pShadeCurrent;
|
|
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
|
|
|
|
if(hSrcVObject->ppZStripInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
// setup for the z-column blitting stuff
|
|
pZInfo=hSrcVObject->ppZStripInfo[ usZStripIndex ];
|
|
if(pZInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
|
|
usZStartLevel=(UINT16)((INT16)usZValue+((INT16)pZInfo->bInitialZChange*Z_STRIP_DELTA_Y));
|
|
// set to odd number of pixels for first column
|
|
|
|
if(LeftSkip > pZInfo->ubFirstZStripWidth)
|
|
{
|
|
usZStartCols=(LeftSkip - pZInfo->ubFirstZStripWidth);
|
|
usZStartCols=20-(usZStartCols%20);
|
|
}
|
|
else if(LeftSkip < pZInfo->ubFirstZStripWidth)
|
|
usZStartCols=(UINT16)(pZInfo->ubFirstZStripWidth - LeftSkip);
|
|
else
|
|
usZStartCols=20;
|
|
|
|
usZColsToGo=usZStartCols;
|
|
|
|
pZArray=pZInfo->pbZChange;
|
|
|
|
if(LeftSkip >= pZInfo->ubFirstZStripWidth)
|
|
{
|
|
// Index into array after doing left clipping
|
|
usZStartIndex=1 + ((LeftSkip-pZInfo->ubFirstZStripWidth)/20);
|
|
|
|
//calculates the Z-value after left-side clipping
|
|
if(usZStartIndex)
|
|
{
|
|
for(usCount=0; usCount < usZStartIndex; usCount++)
|
|
{
|
|
switch(pZArray[usCount])
|
|
{
|
|
case -1: usZStartLevel-=Z_STRIP_DELTA_Y;
|
|
break;
|
|
case 0: //no change
|
|
break;
|
|
case 1: usZStartLevel+=Z_STRIP_DELTA_Y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
usZStartIndex=0;
|
|
|
|
usZLevel=usZStartLevel;
|
|
usZIndex=usZStartIndex;
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
cmp TopSkip, 0 // check for nothing clipped on top
|
|
je LeftSkipSetup
|
|
|
|
|
|
// Skips the number of lines clipped at the top
|
|
TopSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js TopSkipLoop
|
|
jz TSEndLine
|
|
|
|
add esi, ecx
|
|
jmp TopSkipLoop
|
|
|
|
TSEndLine:
|
|
dec TopSkip
|
|
jnz TopSkipLoop
|
|
|
|
|
|
// Start of line loop
|
|
|
|
// Skips the pixels hanging outside the left-side boundry
|
|
LeftSkipSetup:
|
|
|
|
mov Unblitted, 0 // Unblitted counts any pixels left from a run
|
|
mov eax, LeftSkip // after we have skipped enough left-side pixels
|
|
mov LSCount, eax // LSCount counts how many pixels skipped so far
|
|
or eax, eax
|
|
jz BlitLineSetup // check for nothing to skip
|
|
|
|
LeftSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
|
|
or cl, cl
|
|
js LSTrans
|
|
|
|
cmp ecx, LSCount
|
|
je LSSkip2 // if equal, skip whole, and start blit with new run
|
|
jb LSSkip1 // if less, skip whole thing
|
|
|
|
add esi, LSCount // skip partial run, jump into normal loop for rest
|
|
sub ecx, LSCount
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitNTL1 // *** jumps into non-transparent blit loop
|
|
|
|
LSSkip2:
|
|
add esi, ecx // skip whole run, and start blit with new run
|
|
jmp BlitLineSetup
|
|
|
|
|
|
LSSkip1:
|
|
add esi, ecx // skip whole run, continue skipping
|
|
sub LSCount, ecx
|
|
jmp LeftSkipLoop
|
|
|
|
|
|
LSTrans:
|
|
and ecx, 07fH
|
|
cmp ecx, LSCount
|
|
je BlitLineSetup // if equal, skip whole, and start blit with new run
|
|
jb LSTrans1 // if less, skip whole thing
|
|
|
|
sub ecx, LSCount // skip partial run, jump into normal loop for rest
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitTransparent // *** jumps into transparent blit loop
|
|
|
|
|
|
LSTrans1:
|
|
sub LSCount, ecx // skip whole run, continue skipping
|
|
jmp LeftSkipLoop
|
|
|
|
//-------------------------------------------------
|
|
// setup for beginning of line
|
|
|
|
BlitLineSetup:
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
|
|
BlitDispatch:
|
|
|
|
cmp LSCount, 0 // Check to see if we're done blitting
|
|
je RightSkipLoop
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz RSLoop2
|
|
|
|
//--------------------------------
|
|
// blitting non-transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitNTL1:
|
|
mov ax, [ebx] // check z-level of pixel
|
|
cmp ax, usZLevel
|
|
ja BlitNTL2
|
|
|
|
mov ax, usZLevel // update z-level of pixel
|
|
mov [ebx], ax
|
|
|
|
xor eax, eax
|
|
mov al, [esi] // copy pixel
|
|
mov ax, [edx+eax*2]
|
|
mov [edi], ax
|
|
|
|
BlitNTL2:
|
|
inc esi
|
|
add edi, 2
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitNTL6
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitNTL5 // dir = 0 no change
|
|
js BlitNTL4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitNTL5
|
|
|
|
BlitNTL4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitNTL5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitNTL6:
|
|
dec LSCount // decrement pixel length to blit
|
|
jz RightSkipLoop // done blitting the visible line
|
|
|
|
dec ecx
|
|
jnz BlitNTL1 // continue current run
|
|
|
|
jmp BlitDispatch // done current run, go for another
|
|
|
|
|
|
//----------------------------
|
|
// skipping transparent pixels
|
|
|
|
BlitTransparent: // skip transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitTrans2:
|
|
|
|
add edi, 2 // move up the destination pointer
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitTrans1
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitTrans5 // dir = 0 no change
|
|
js BlitTrans4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitTrans5
|
|
|
|
BlitTrans4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitTrans5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitTrans1:
|
|
|
|
dec LSCount // decrement the pixels to blit
|
|
jz RightSkipLoop // done the line
|
|
|
|
dec ecx
|
|
jnz BlitTrans2
|
|
|
|
jmp BlitDispatch
|
|
|
|
//---------------------------------------------
|
|
// Scans the ETRLE until it finds an EOL marker
|
|
|
|
RightSkipLoop:
|
|
|
|
|
|
RSLoop1:
|
|
mov al, [esi]
|
|
inc esi
|
|
or al, al
|
|
jnz RSLoop1
|
|
|
|
RSLoop2:
|
|
|
|
dec BlitHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
|
|
// reset all the z-level stuff for a new line
|
|
|
|
mov ax, usZStartLevel
|
|
mov usZLevel, ax
|
|
mov ax, usZStartIndex
|
|
mov usZIndex, ax
|
|
mov ax, usZStartCols
|
|
mov usZColsToGo, ax
|
|
|
|
|
|
jmp LeftSkipSetup
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/**********************************************************************************************
|
|
Blt8BPPDataTo16BPPBufferTransZIncObscureClip
|
|
|
|
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
|
|
buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
|
|
pixel's Z level is below that of the current pixel, it is written on, and the Z value is
|
|
updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
|
|
must be the same dimensions (including Pitch) as the destination.
|
|
|
|
//ATE: This blitter makes the values that are =< z value pixellate rather than not
|
|
// render at all
|
|
|
|
**********************************************************************************************/
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
|
|
{
|
|
UINT16 *p16BPPPalette;
|
|
UINT32 uiOffset, uiLineFlag;
|
|
UINT32 usHeight, usWidth, Unblitted;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
|
|
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
|
|
UINT16 usZLevel, usZStartLevel, usZColsToGo, usZStartIndex, usCount, usZIndex, usZStartCols;
|
|
INT8 *pZArray;
|
|
ZStripInfo *pZInfo;
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
|
|
if(clipregion==NULL)
|
|
{
|
|
ClipX1=ClippingRect.iLeft;
|
|
ClipY1=ClippingRect.iTop;
|
|
ClipX2=ClippingRect.iRight;
|
|
ClipY2=ClippingRect.iBottom;
|
|
}
|
|
else
|
|
{
|
|
ClipX1=clipregion->iLeft;
|
|
ClipY1=clipregion->iTop;
|
|
ClipX2=clipregion->iRight;
|
|
ClipY2=clipregion->iBottom;
|
|
}
|
|
|
|
// Calculate rows hanging off each side of the screen
|
|
LeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
|
|
RightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
|
|
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
|
|
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
|
|
|
|
uiLineFlag=(iTempY&1);
|
|
|
|
// calculate the remaining rows and columns to blit
|
|
BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
|
|
BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
|
|
|
|
// check if whole thing is clipped
|
|
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
|
|
return(TRUE);
|
|
|
|
// check if whole thing is clipped
|
|
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
|
|
return(TRUE);
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
p16BPPPalette = hSrcVObject->pShadeCurrent;
|
|
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
|
|
|
|
if(hSrcVObject->ppZStripInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
// setup for the z-column blitting stuff
|
|
pZInfo=hSrcVObject->ppZStripInfo[usIndex];
|
|
if(pZInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
|
|
usZStartLevel=(UINT16)((INT16)usZValue+((INT16)pZInfo->bInitialZChange*Z_STRIP_DELTA_Y));
|
|
// set to odd number of pixels for first column
|
|
|
|
if(LeftSkip > pZInfo->ubFirstZStripWidth)
|
|
{
|
|
usZStartCols=(LeftSkip - pZInfo->ubFirstZStripWidth);
|
|
usZStartCols=20-(usZStartCols%20);
|
|
}
|
|
else if(LeftSkip < pZInfo->ubFirstZStripWidth)
|
|
usZStartCols=(UINT16)(pZInfo->ubFirstZStripWidth - LeftSkip);
|
|
else
|
|
usZStartCols=20;
|
|
|
|
usZColsToGo=usZStartCols;
|
|
|
|
pZArray=pZInfo->pbZChange;
|
|
|
|
if(LeftSkip >= pZInfo->ubFirstZStripWidth)
|
|
{
|
|
// Index into array after doing left clipping
|
|
usZStartIndex=1 + ((LeftSkip-pZInfo->ubFirstZStripWidth)/20);
|
|
|
|
//calculates the Z-value after left-side clipping
|
|
if(usZStartIndex)
|
|
{
|
|
for(usCount=0; usCount < usZStartIndex; usCount++)
|
|
{
|
|
switch(pZArray[usCount])
|
|
{
|
|
case -1: usZStartLevel-=Z_STRIP_DELTA_Y;
|
|
break;
|
|
case 0: //no change
|
|
break;
|
|
case 1: usZStartLevel+=Z_STRIP_DELTA_Y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
usZStartIndex=0;
|
|
|
|
usZLevel=usZStartLevel;
|
|
usZIndex=usZStartIndex;
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
cmp TopSkip, 0 // check for nothing clipped on top
|
|
je LeftSkipSetup
|
|
|
|
|
|
// Skips the number of lines clipped at the top
|
|
TopSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js TopSkipLoop
|
|
jz TSEndLine
|
|
|
|
add esi, ecx
|
|
jmp TopSkipLoop
|
|
|
|
TSEndLine:
|
|
|
|
xor uiLineFlag, 1
|
|
dec TopSkip
|
|
jnz TopSkipLoop
|
|
|
|
|
|
// Start of line loop
|
|
|
|
// Skips the pixels hanging outside the left-side boundry
|
|
LeftSkipSetup:
|
|
|
|
mov Unblitted, 0 // Unblitted counts any pixels left from a run
|
|
mov eax, LeftSkip // after we have skipped enough left-side pixels
|
|
mov LSCount, eax // LSCount counts how many pixels skipped so far
|
|
or eax, eax
|
|
jz BlitLineSetup // check for nothing to skip
|
|
|
|
LeftSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
|
|
or cl, cl
|
|
js LSTrans
|
|
|
|
cmp ecx, LSCount
|
|
je LSSkip2 // if equal, skip whole, and start blit with new run
|
|
jb LSSkip1 // if less, skip whole thing
|
|
|
|
add esi, LSCount // skip partial run, jump into normal loop for rest
|
|
sub ecx, LSCount
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitNTL1 // *** jumps into non-transparent blit loop
|
|
|
|
LSSkip2:
|
|
add esi, ecx // skip whole run, and start blit with new run
|
|
jmp BlitLineSetup
|
|
|
|
|
|
LSSkip1:
|
|
add esi, ecx // skip whole run, continue skipping
|
|
sub LSCount, ecx
|
|
jmp LeftSkipLoop
|
|
|
|
|
|
LSTrans:
|
|
and ecx, 07fH
|
|
cmp ecx, LSCount
|
|
je BlitLineSetup // if equal, skip whole, and start blit with new run
|
|
jb LSTrans1 // if less, skip whole thing
|
|
|
|
sub ecx, LSCount // skip partial run, jump into normal loop for rest
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitTransparent // *** jumps into transparent blit loop
|
|
|
|
|
|
LSTrans1:
|
|
sub LSCount, ecx // skip whole run, continue skipping
|
|
jmp LeftSkipLoop
|
|
|
|
//-------------------------------------------------
|
|
// setup for beginning of line
|
|
|
|
BlitLineSetup:
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
|
|
BlitDispatch:
|
|
|
|
cmp LSCount, 0 // Check to see if we're done blitting
|
|
je RightSkipLoop
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz RSLoop2
|
|
|
|
//--------------------------------
|
|
// blitting non-transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitNTL1:
|
|
mov ax, [ebx] // check z-level of pixel
|
|
cmp ax, usZLevel
|
|
jae BlitPixellate1
|
|
jmp BlitPixel1
|
|
|
|
BlitPixellate1:
|
|
|
|
// OK, DO PIXELLATE SCHEME HERE!
|
|
test uiLineFlag, 1
|
|
jz BlitSkip1
|
|
|
|
test edi, 2
|
|
jz BlitNTL2
|
|
jmp BlitPixel1
|
|
|
|
BlitSkip1:
|
|
test edi, 2
|
|
jnz BlitNTL2
|
|
|
|
BlitPixel1:
|
|
|
|
mov ax, usZLevel // update z-level of pixel
|
|
mov [ebx], ax
|
|
|
|
xor eax, eax
|
|
mov al, [esi] // copy pixel
|
|
mov ax, [edx+eax*2]
|
|
mov [edi], ax
|
|
|
|
BlitNTL2:
|
|
inc esi
|
|
add edi, 2
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitNTL6
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitNTL5 // dir = 0 no change
|
|
js BlitNTL4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitNTL5
|
|
|
|
BlitNTL4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitNTL5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitNTL6:
|
|
dec LSCount // decrement pixel length to blit
|
|
jz RightSkipLoop // done blitting the visible line
|
|
|
|
dec ecx
|
|
jnz BlitNTL1 // continue current run
|
|
|
|
jmp BlitDispatch // done current run, go for another
|
|
|
|
|
|
//----------------------------
|
|
// skipping transparent pixels
|
|
|
|
BlitTransparent: // skip transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitTrans2:
|
|
|
|
add edi, 2 // move up the destination pointer
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitTrans1
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitTrans5 // dir = 0 no change
|
|
js BlitTrans4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_STRIP_DELTA_Y
|
|
jmp BlitTrans5
|
|
|
|
BlitTrans4:
|
|
sub dx, Z_STRIP_DELTA_Y
|
|
|
|
BlitTrans5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitTrans1:
|
|
|
|
dec LSCount // decrement the pixels to blit
|
|
jz RightSkipLoop // done the line
|
|
|
|
dec ecx
|
|
jnz BlitTrans2
|
|
|
|
jmp BlitDispatch
|
|
|
|
//---------------------------------------------
|
|
// Scans the ETRLE until it finds an EOL marker
|
|
|
|
RightSkipLoop:
|
|
|
|
|
|
RSLoop1:
|
|
mov al, [esi]
|
|
inc esi
|
|
or al, al
|
|
jnz RSLoop1
|
|
|
|
RSLoop2:
|
|
|
|
xor uiLineFlag, 1
|
|
dec BlitHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
|
|
// reset all the z-level stuff for a new line
|
|
|
|
mov ax, usZStartLevel
|
|
mov usZLevel, ax
|
|
mov ax, usZStartIndex
|
|
mov usZIndex, ax
|
|
mov ax, usZStartCols
|
|
mov usZColsToGo, ax
|
|
|
|
|
|
jmp LeftSkipSetup
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
// Blitter Specs
|
|
// 1 ) 8 to 16 bpp
|
|
// 2 ) strip z-blitter
|
|
// 3 ) clipped
|
|
// 4 ) trans shadow - if value is 254, makes a shadow
|
|
//
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette )
|
|
{
|
|
UINT32 uiOffset, uiLineFlag;
|
|
UINT32 usHeight, usWidth, Unblitted;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
|
|
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
|
|
UINT16 usZLevel, usZStartLevel, usZColsToGo, usZStartIndex, usCount, usZIndex, usZStartCols;
|
|
INT8 *pZArray;
|
|
ZStripInfo *pZInfo;
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
if(clipregion==NULL)
|
|
{
|
|
ClipX1=ClippingRect.iLeft;
|
|
ClipY1=ClippingRect.iTop;
|
|
ClipX2=ClippingRect.iRight;
|
|
ClipY2=ClippingRect.iBottom;
|
|
}
|
|
else
|
|
{
|
|
ClipX1=clipregion->iLeft;
|
|
ClipY1=clipregion->iTop;
|
|
ClipX2=clipregion->iRight;
|
|
ClipY2=clipregion->iBottom;
|
|
}
|
|
|
|
// Calculate rows hanging off each side of the screen
|
|
LeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
|
|
RightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
|
|
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
|
|
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
|
|
|
|
uiLineFlag=(iTempY&1);
|
|
|
|
// calculate the remaining rows and columns to blit
|
|
BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
|
|
BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
|
|
|
|
// check if whole thing is clipped
|
|
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
|
|
return(TRUE);
|
|
|
|
// check if whole thing is clipped
|
|
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
|
|
return(TRUE);
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
|
|
|
|
if(hSrcVObject->ppZStripInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
// setup for the z-column blitting stuff
|
|
pZInfo=hSrcVObject->ppZStripInfo[sZIndex];
|
|
if(pZInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
|
|
usZStartLevel=(UINT16)((INT16)usZValue+((INT16)pZInfo->bInitialZChange*Z_SUBLAYERS*10));
|
|
|
|
if(LeftSkip > pZInfo->ubFirstZStripWidth)
|
|
{
|
|
usZStartCols=(LeftSkip - pZInfo->ubFirstZStripWidth);
|
|
usZStartCols=20-(usZStartCols%20);
|
|
}
|
|
else if(LeftSkip < pZInfo->ubFirstZStripWidth)
|
|
usZStartCols=(UINT16)(pZInfo->ubFirstZStripWidth - LeftSkip);
|
|
else
|
|
usZStartCols=20;
|
|
|
|
// set to odd number of pixels for first column
|
|
usZColsToGo=usZStartCols;
|
|
|
|
pZArray=pZInfo->pbZChange;
|
|
|
|
if(LeftSkip >= usZColsToGo)
|
|
{
|
|
// Index into array after doing left clipping
|
|
usZStartIndex=1 + ((LeftSkip-pZInfo->ubFirstZStripWidth)/20);
|
|
|
|
//calculates the Z-value after left-side clipping
|
|
if(usZStartIndex)
|
|
{
|
|
for(usCount=0; usCount < usZStartIndex; usCount++)
|
|
{
|
|
switch(pZArray[usCount])
|
|
{
|
|
case -1: usZStartLevel-=Z_SUBLAYERS;
|
|
break;
|
|
case 0: //no change
|
|
break;
|
|
case 1: usZStartLevel+=Z_SUBLAYERS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
usZStartIndex=0;
|
|
|
|
usZLevel=usZStartLevel;
|
|
usZIndex=usZStartIndex;
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
cmp TopSkip, 0 // check for nothing clipped on top
|
|
je LeftSkipSetup
|
|
|
|
|
|
// Skips the number of lines clipped at the top
|
|
TopSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js TopSkipLoop
|
|
jz TSEndLine
|
|
|
|
add esi, ecx
|
|
jmp TopSkipLoop
|
|
|
|
TSEndLine:
|
|
|
|
xor uiLineFlag, 1
|
|
dec TopSkip
|
|
jnz TopSkipLoop
|
|
|
|
|
|
// Start of line loop
|
|
|
|
// Skips the pixels hanging outside the left-side boundry
|
|
LeftSkipSetup:
|
|
|
|
mov Unblitted, 0 // Unblitted counts any pixels left from a run
|
|
mov eax, LeftSkip // after we have skipped enough left-side pixels
|
|
mov LSCount, eax // LSCount counts how many pixels skipped so far
|
|
or eax, eax
|
|
jz BlitLineSetup // check for nothing to skip
|
|
|
|
LeftSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
|
|
or cl, cl
|
|
js LSTrans
|
|
|
|
cmp ecx, LSCount
|
|
je LSSkip2 // if equal, skip whole, and start blit with new run
|
|
jb LSSkip1 // if less, skip whole thing
|
|
|
|
add esi, LSCount // skip partial run, jump into normal loop for rest
|
|
sub ecx, LSCount
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitNTL1 // *** jumps into non-transparent blit loop
|
|
|
|
LSSkip2:
|
|
add esi, ecx // skip whole run, and start blit with new run
|
|
jmp BlitLineSetup
|
|
|
|
|
|
LSSkip1:
|
|
add esi, ecx // skip whole run, continue skipping
|
|
sub LSCount, ecx
|
|
jmp LeftSkipLoop
|
|
|
|
|
|
LSTrans:
|
|
and ecx, 07fH
|
|
cmp ecx, LSCount
|
|
je BlitLineSetup // if equal, skip whole, and start blit with new run
|
|
jb LSTrans1 // if less, skip whole thing
|
|
|
|
sub ecx, LSCount // skip partial run, jump into normal loop for rest
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
|
|
mov Unblitted, 0
|
|
jmp BlitTransparent // *** jumps into transparent blit loop
|
|
|
|
|
|
LSTrans1:
|
|
sub LSCount, ecx // skip whole run, continue skipping
|
|
jmp LeftSkipLoop
|
|
|
|
//-------------------------------------------------
|
|
// setup for beginning of line
|
|
|
|
BlitLineSetup:
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
|
|
BlitDispatch:
|
|
|
|
cmp LSCount, 0 // Check to see if we're done blitting
|
|
je RightSkipLoop
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz RSLoop2
|
|
|
|
//--------------------------------
|
|
// blitting non-transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitNTL1:
|
|
mov ax, [ebx] // check z-level of pixel
|
|
cmp ax, usZLevel
|
|
jae BlitPixellate1
|
|
jmp BlitPixel1
|
|
|
|
BlitPixellate1:
|
|
|
|
// OK, DO PIXELLATE SCHEME HERE!
|
|
test uiLineFlag, 1
|
|
jz BlitSkip1
|
|
|
|
test edi, 2
|
|
jz BlitNTL2
|
|
jmp BlitPixel1
|
|
|
|
BlitSkip1:
|
|
test edi, 2
|
|
jnz BlitNTL2
|
|
|
|
BlitPixel1:
|
|
|
|
mov ax, usZLevel // update z-level of pixel
|
|
mov [ebx], ax
|
|
|
|
// Check for shadow...
|
|
xor eax, eax
|
|
mov al, [esi]
|
|
cmp al, 254
|
|
jne BlitNTL66
|
|
|
|
mov ax, [edi]
|
|
mov ax, ShadeTable[eax*2]
|
|
mov [edi], ax
|
|
jmp BlitNTL2
|
|
|
|
BlitNTL66:
|
|
|
|
mov ax, [edx+eax*2] // Copy pixel
|
|
mov [edi], ax
|
|
|
|
BlitNTL2:
|
|
inc esi
|
|
add edi, 2
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitNTL6
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitNTL5 // dir = 0 no change
|
|
js BlitNTL4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_SUBLAYERS
|
|
jmp BlitNTL5
|
|
|
|
BlitNTL4:
|
|
sub dx, Z_SUBLAYERS
|
|
|
|
BlitNTL5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitNTL6:
|
|
dec LSCount // decrement pixel length to blit
|
|
jz RightSkipLoop // done blitting the visible line
|
|
|
|
dec ecx
|
|
jnz BlitNTL1 // continue current run
|
|
|
|
jmp BlitDispatch // done current run, go for another
|
|
|
|
|
|
//----------------------------
|
|
// skipping transparent pixels
|
|
|
|
BlitTransparent: // skip transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitTrans2:
|
|
|
|
add edi, 2 // move up the destination pointer
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitTrans1
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitTrans5 // dir = 0 no change
|
|
js BlitTrans4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_SUBLAYERS
|
|
jmp BlitTrans5
|
|
|
|
BlitTrans4:
|
|
sub dx, Z_SUBLAYERS
|
|
|
|
BlitTrans5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitTrans1:
|
|
|
|
dec LSCount // decrement the pixels to blit
|
|
jz RightSkipLoop // done the line
|
|
|
|
dec ecx
|
|
jnz BlitTrans2
|
|
|
|
jmp BlitDispatch
|
|
|
|
//---------------------------------------------
|
|
// Scans the ETRLE until it finds an EOL marker
|
|
|
|
RightSkipLoop:
|
|
|
|
|
|
RSLoop1:
|
|
mov al, [esi]
|
|
inc esi
|
|
or al, al
|
|
jnz RSLoop1
|
|
|
|
RSLoop2:
|
|
|
|
xor uiLineFlag, 1
|
|
dec BlitHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
|
|
// reset all the z-level stuff for a new line
|
|
|
|
mov ax, usZStartLevel
|
|
mov usZLevel, ax
|
|
mov ax, usZStartIndex
|
|
mov usZIndex, ax
|
|
mov ax, usZStartCols
|
|
mov usZColsToGo, ax
|
|
|
|
|
|
jmp LeftSkipSetup
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
void CorrectRenderCenter( INT16 sRenderX, INT16 sRenderY, INT16 *pSNewX, INT16 *pSNewY )
|
|
{
|
|
INT16 sScreenX, sScreenY;
|
|
INT16 sNumXSteps, sNumYSteps;
|
|
|
|
// Use radar scale values to get screen values, then convert ot map values, rounding to nearest middle tile
|
|
sScreenX = (INT16) sRenderX;
|
|
sScreenY = (INT16) sRenderY;
|
|
|
|
// Adjust for offsets!
|
|
sScreenX += 0;
|
|
sScreenY += 10;
|
|
|
|
// Adjust to viewport start!
|
|
sScreenX -= ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 );
|
|
sScreenY -= ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 );
|
|
|
|
//Make sure these coordinates are multiples of scroll steps
|
|
sNumXSteps = sScreenX / gubNewScrollXSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ];
|
|
sNumYSteps = sScreenY / gubNewScrollYSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ];
|
|
|
|
|
|
sScreenX = ( sNumXSteps * gubNewScrollXSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ] );
|
|
sScreenY = ( sNumYSteps * gubNewScrollYSpeeds[ gfDoVideoScroll ][ gubCurScrollSpeedID ]);
|
|
|
|
// Adjust back
|
|
sScreenX += ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 );
|
|
sScreenY += ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 );
|
|
|
|
*pSNewX = sScreenX;
|
|
*pSNewY = sScreenY;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Blitter Specs
|
|
// 1 ) 8 to 16 bpp
|
|
// 2 ) strip z-blitter
|
|
// 3 ) clipped
|
|
// 4 ) trans shadow - if value is 254, makes a shadow
|
|
//
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette )
|
|
{
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth, Unblitted;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
|
|
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
|
|
UINT16 usZLevel, usZStartLevel, usZColsToGo, usZStartIndex, usCount, usZIndex, usZStartCols;
|
|
INT8 *pZArray;
|
|
ZStripInfo *pZInfo;
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
if(clipregion==NULL)
|
|
{
|
|
ClipX1=ClippingRect.iLeft;
|
|
ClipY1=ClippingRect.iTop;
|
|
ClipX2=ClippingRect.iRight;
|
|
ClipY2=ClippingRect.iBottom;
|
|
}
|
|
else
|
|
{
|
|
ClipX1=clipregion->iLeft;
|
|
ClipY1=clipregion->iTop;
|
|
ClipX2=clipregion->iRight;
|
|
ClipY2=clipregion->iBottom;
|
|
}
|
|
|
|
// Calculate rows hanging off each side of the screen
|
|
LeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
|
|
RightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
|
|
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
|
|
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
|
|
|
|
// calculate the remaining rows and columns to blit
|
|
BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
|
|
BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
|
|
|
|
// check if whole thing is clipped
|
|
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
|
|
return(TRUE);
|
|
|
|
// check if whole thing is clipped
|
|
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
|
|
return(TRUE);
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
|
|
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
|
|
|
|
if(hSrcVObject->ppZStripInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
// setup for the z-column blitting stuff
|
|
pZInfo=hSrcVObject->ppZStripInfo[sZIndex];
|
|
if(pZInfo==NULL)
|
|
{
|
|
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_0, String("Missing Z-Strip info on multi-Z object"));
|
|
return(FALSE);
|
|
}
|
|
|
|
usZStartLevel=(UINT16)((INT16)usZValue+((INT16)pZInfo->bInitialZChange*Z_SUBLAYERS*10));
|
|
|
|
if(LeftSkip > pZInfo->ubFirstZStripWidth)
|
|
{
|
|
usZStartCols=(LeftSkip - pZInfo->ubFirstZStripWidth);
|
|
usZStartCols=20-(usZStartCols%20);
|
|
}
|
|
else if(LeftSkip < pZInfo->ubFirstZStripWidth)
|
|
usZStartCols=(UINT16)(pZInfo->ubFirstZStripWidth - LeftSkip);
|
|
else
|
|
usZStartCols=20;
|
|
|
|
// set to odd number of pixels for first column
|
|
usZColsToGo=usZStartCols;
|
|
|
|
pZArray=pZInfo->pbZChange;
|
|
|
|
if(LeftSkip >= usZColsToGo)
|
|
{
|
|
// Index into array after doing left clipping
|
|
usZStartIndex=1 + ((LeftSkip-pZInfo->ubFirstZStripWidth)/20);
|
|
|
|
//calculates the Z-value after left-side clipping
|
|
if(usZStartIndex)
|
|
{
|
|
for(usCount=0; usCount < usZStartIndex; usCount++)
|
|
{
|
|
switch(pZArray[usCount])
|
|
{
|
|
case -1: usZStartLevel-=Z_SUBLAYERS;
|
|
break;
|
|
case 0: //no change
|
|
break;
|
|
case 1: usZStartLevel+=Z_SUBLAYERS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
usZStartIndex=0;
|
|
|
|
usZLevel=usZStartLevel;
|
|
usZIndex=usZStartIndex;
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
cmp TopSkip, 0 // check for nothing clipped on top
|
|
je LeftSkipSetup
|
|
|
|
|
|
// Skips the number of lines clipped at the top
|
|
TopSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js TopSkipLoop
|
|
jz TSEndLine
|
|
|
|
add esi, ecx
|
|
jmp TopSkipLoop
|
|
|
|
TSEndLine:
|
|
dec TopSkip
|
|
jnz TopSkipLoop
|
|
|
|
|
|
// Start of line loop
|
|
|
|
// Skips the pixels hanging outside the left-side boundry
|
|
LeftSkipSetup:
|
|
|
|
mov Unblitted, 0 // Unblitted counts any pixels left from a run
|
|
mov eax, LeftSkip // after we have skipped enough left-side pixels
|
|
mov LSCount, eax // LSCount counts how many pixels skipped so far
|
|
or eax, eax
|
|
jz BlitLineSetup // check for nothing to skip
|
|
|
|
LeftSkipLoop:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
|
|
or cl, cl
|
|
js LSTrans
|
|
|
|
cmp ecx, LSCount
|
|
je LSSkip2 // if equal, skip whole, and start blit with new run
|
|
jb LSSkip1 // if less, skip whole thing
|
|
|
|
add esi, LSCount // skip partial run, jump into normal loop for rest
|
|
sub ecx, LSCount
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
jmp BlitNTL1 // *** jumps into non-transparent blit loop
|
|
|
|
LSSkip2:
|
|
add esi, ecx // skip whole run, and start blit with new run
|
|
jmp BlitLineSetup
|
|
|
|
|
|
LSSkip1:
|
|
add esi, ecx // skip whole run, continue skipping
|
|
sub LSCount, ecx
|
|
jmp LeftSkipLoop
|
|
|
|
|
|
LSTrans:
|
|
and ecx, 07fH
|
|
cmp ecx, LSCount
|
|
je BlitLineSetup // if equal, skip whole, and start blit with new run
|
|
jb LSTrans1 // if less, skip whole thing
|
|
|
|
sub ecx, LSCount // skip partial run, jump into normal loop for rest
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
|
|
mov Unblitted, 0
|
|
jmp BlitTransparent // *** jumps into transparent blit loop
|
|
|
|
|
|
LSTrans1:
|
|
sub LSCount, ecx // skip whole run, continue skipping
|
|
jmp LeftSkipLoop
|
|
|
|
//-------------------------------------------------
|
|
// setup for beginning of line
|
|
|
|
BlitLineSetup:
|
|
mov eax, BlitLength
|
|
mov LSCount, eax
|
|
mov Unblitted, 0
|
|
|
|
BlitDispatch:
|
|
|
|
cmp LSCount, 0 // Check to see if we're done blitting
|
|
je RightSkipLoop
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz RSLoop2
|
|
|
|
//--------------------------------
|
|
// blitting non-transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitNTL1:
|
|
mov ax, [ebx] // check z-level of pixel
|
|
cmp ax, usZLevel
|
|
ja BlitNTL2
|
|
|
|
mov ax, usZLevel // update z-level of pixel
|
|
mov [ebx], ax
|
|
|
|
// Check for shadow...
|
|
xor eax, eax
|
|
mov al, [esi]
|
|
cmp al, 254
|
|
jne BlitNTL66
|
|
|
|
mov ax, [edi]
|
|
mov ax, ShadeTable[eax*2]
|
|
mov [edi], ax
|
|
jmp BlitNTL2
|
|
|
|
BlitNTL66:
|
|
|
|
mov ax, [edx+eax*2] // Copy pixel
|
|
mov [edi], ax
|
|
|
|
BlitNTL2:
|
|
inc esi
|
|
add edi, 2
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitNTL6
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitNTL5 // dir = 0 no change
|
|
js BlitNTL4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_SUBLAYERS
|
|
jmp BlitNTL5
|
|
|
|
BlitNTL4:
|
|
sub dx, Z_SUBLAYERS
|
|
|
|
BlitNTL5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitNTL6:
|
|
dec LSCount // decrement pixel length to blit
|
|
jz RightSkipLoop // done blitting the visible line
|
|
|
|
dec ecx
|
|
jnz BlitNTL1 // continue current run
|
|
|
|
jmp BlitDispatch // done current run, go for another
|
|
|
|
|
|
//----------------------------
|
|
// skipping transparent pixels
|
|
|
|
BlitTransparent: // skip transparent pixels
|
|
|
|
and ecx, 07fH
|
|
|
|
BlitTrans2:
|
|
|
|
add edi, 2 // move up the destination pointer
|
|
add ebx, 2
|
|
|
|
dec usZColsToGo
|
|
jnz BlitTrans1
|
|
|
|
// update the z-level according to the z-table
|
|
|
|
push edx
|
|
mov edx, pZArray // get pointer to array
|
|
xor eax, eax
|
|
mov ax, usZIndex // pick up the current array index
|
|
add edx, eax
|
|
inc eax // increment it
|
|
mov usZIndex, ax // store incremented value
|
|
|
|
mov al, [edx] // get direction instruction
|
|
mov dx, usZLevel // get current z-level
|
|
|
|
or al, al
|
|
jz BlitTrans5 // dir = 0 no change
|
|
js BlitTrans4 // dir < 0 z-level down
|
|
// dir > 0 z-level up (default)
|
|
add dx, Z_SUBLAYERS
|
|
jmp BlitTrans5
|
|
|
|
BlitTrans4:
|
|
sub dx, Z_SUBLAYERS
|
|
|
|
BlitTrans5:
|
|
mov usZLevel, dx // store the now-modified z-level
|
|
mov usZColsToGo, 20 // reset the next z-level change to 20 cols
|
|
pop edx
|
|
|
|
BlitTrans1:
|
|
|
|
dec LSCount // decrement the pixels to blit
|
|
jz RightSkipLoop // done the line
|
|
|
|
dec ecx
|
|
jnz BlitTrans2
|
|
|
|
jmp BlitDispatch
|
|
|
|
//---------------------------------------------
|
|
// Scans the ETRLE until it finds an EOL marker
|
|
|
|
RightSkipLoop:
|
|
|
|
|
|
RSLoop1:
|
|
mov al, [esi]
|
|
inc esi
|
|
or al, al
|
|
jnz RSLoop1
|
|
|
|
RSLoop2:
|
|
|
|
dec BlitHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
|
|
// reset all the z-level stuff for a new line
|
|
|
|
mov ax, usZStartLevel
|
|
mov usZLevel, ax
|
|
mov ax, usZStartIndex
|
|
mov usZIndex, ax
|
|
mov ax, usZStartCols
|
|
mov usZColsToGo, ax
|
|
|
|
|
|
jmp LeftSkipSetup
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderRoomInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS )
|
|
{
|
|
INT8 bXOddFlag = 0;
|
|
INT16 sAnchorPosX_M, sAnchorPosY_M;
|
|
INT16 sAnchorPosX_S, sAnchorPosY_S;
|
|
INT16 sTempPosX_M, sTempPosY_M;
|
|
INT16 sTempPosX_S, sTempPosY_S;
|
|
BOOLEAN fEndRenderRow = FALSE, fEndRenderCol = FALSE;
|
|
UINT16 usTileIndex;
|
|
INT16 sX, sY;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
|
|
|
|
// Begin Render Loop
|
|
sAnchorPosX_M = sStartPointX_M;
|
|
sAnchorPosY_M = sStartPointY_M;
|
|
sAnchorPosX_S = sStartPointX_S;
|
|
sAnchorPosY_S = sStartPointY_S;
|
|
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
do
|
|
{
|
|
|
|
fEndRenderRow = FALSE;
|
|
sTempPosX_M = sAnchorPosX_M;
|
|
sTempPosY_M = sAnchorPosY_M;
|
|
sTempPosX_S = sAnchorPosX_S;
|
|
sTempPosY_S = sAnchorPosY_S;
|
|
|
|
if(bXOddFlag > 0)
|
|
sTempPosX_S += 20;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
usTileIndex=FASTMAPROWCOLTOPOS( sTempPosY_M, sTempPosX_M );
|
|
|
|
if ( usTileIndex < GRIDSIZE )
|
|
{
|
|
sX = sTempPosX_S + ( WORLD_TILE_X / 2 ) - 5;
|
|
sY = sTempPosY_S + ( WORLD_TILE_Y / 2 ) - 5;
|
|
|
|
// THIS ROOM STUFF IS ONLY DONE IN THE EDITOR...
|
|
// ADJUST BY SHEIGHT
|
|
sY -= gpWorldLevelData[ usTileIndex ].sHeight;
|
|
//sY += gsRenderHeight;
|
|
|
|
if ( gubWorldRoomInfo[ usTileIndex ] != NO_ROOM )
|
|
{
|
|
SetFont( SMALLCOMPFONT );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, gsVIEWPORT_END_Y, FALSE );
|
|
switch( gubWorldRoomInfo[ usTileIndex ] % 5 )
|
|
{
|
|
case 0: SetFontForeground( FONT_GRAY3 ); break;
|
|
case 1: SetFontForeground( FONT_YELLOW ); break;
|
|
case 2: SetFontForeground( FONT_LTRED ); break;
|
|
case 3: SetFontForeground( FONT_LTBLUE ); break;
|
|
case 4: SetFontForeground( FONT_LTGREEN );break;
|
|
}
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", gubWorldRoomInfo[ usTileIndex ] );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
}
|
|
}
|
|
|
|
sTempPosX_S += 40;
|
|
sTempPosX_M ++;
|
|
sTempPosY_M --;
|
|
|
|
if ( sTempPosX_S >= sEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
sAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
sAnchorPosX_M ++;
|
|
}
|
|
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
sAnchorPosY_S += 10;
|
|
|
|
if ( sAnchorPosY_S >= sEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
void RenderFOVDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS )
|
|
{
|
|
INT8 bXOddFlag = 0;
|
|
INT16 sAnchorPosX_M, sAnchorPosY_M;
|
|
INT16 sAnchorPosX_S, sAnchorPosY_S;
|
|
INT16 sTempPosX_M, sTempPosY_M;
|
|
INT16 sTempPosX_S, sTempPosY_S;
|
|
BOOLEAN fEndRenderRow = FALSE, fEndRenderCol = FALSE;
|
|
UINT16 usTileIndex;
|
|
INT16 sX, sY;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
|
|
|
|
// Begin Render Loop
|
|
sAnchorPosX_M = sStartPointX_M;
|
|
sAnchorPosY_M = sStartPointY_M;
|
|
sAnchorPosX_S = sStartPointX_S;
|
|
sAnchorPosY_S = sStartPointY_S;
|
|
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
do
|
|
{
|
|
|
|
fEndRenderRow = FALSE;
|
|
sTempPosX_M = sAnchorPosX_M;
|
|
sTempPosY_M = sAnchorPosY_M;
|
|
sTempPosX_S = sAnchorPosX_S;
|
|
sTempPosY_S = sAnchorPosY_S;
|
|
|
|
if(bXOddFlag > 0)
|
|
sTempPosX_S += 20;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
usTileIndex=FASTMAPROWCOLTOPOS( sTempPosY_M, sTempPosX_M );
|
|
|
|
if ( usTileIndex < GRIDSIZE )
|
|
{
|
|
sX = sTempPosX_S + ( WORLD_TILE_X / 2 ) - 5;
|
|
sY = sTempPosY_S + ( WORLD_TILE_Y / 2 ) - 5;
|
|
|
|
// Adjust for interface level
|
|
sY -= gpWorldLevelData[ usTileIndex ].sHeight;
|
|
sY += gsRenderHeight;
|
|
|
|
if ( gubFOVDebugInfoInfo[ usTileIndex ] != 0 )
|
|
{
|
|
SetFont( SMALLCOMPFONT );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, gsVIEWPORT_END_Y, FALSE );
|
|
SetFontForeground( FONT_GRAY3 );
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", gubFOVDebugInfoInfo[ usTileIndex ] );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
|
|
|
|
Blt8BPPDataTo16BPPBufferTransparentClip((UINT16*)pDestBuf, uiDestPitchBYTES, gTileDatabase[0].hTileSurface, sTempPosX_S, sTempPosY_S, 0, &gClippingRect );
|
|
|
|
}
|
|
|
|
if ( gubGridNoMarkers[ usTileIndex ] == gubGridNoValue )
|
|
{
|
|
SetFont( SMALLCOMPFONT );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, gsVIEWPORT_END_Y, FALSE );
|
|
SetFontForeground( FONT_FCOLOR_YELLOW );
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY + 4 , L"x" );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
}
|
|
|
|
}
|
|
|
|
sTempPosX_S += 40;
|
|
sTempPosX_M ++;
|
|
sTempPosY_M --;
|
|
|
|
if ( sTempPosX_S >= sEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
sAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
sAnchorPosX_M ++;
|
|
}
|
|
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
sAnchorPosY_S += 10;
|
|
|
|
if ( sAnchorPosY_S >= sEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
}
|
|
|
|
void RenderCoverDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS )
|
|
{
|
|
INT8 bXOddFlag = 0;
|
|
INT16 sAnchorPosX_M, sAnchorPosY_M;
|
|
INT16 sAnchorPosX_S, sAnchorPosY_S;
|
|
INT16 sTempPosX_M, sTempPosY_M;
|
|
INT16 sTempPosX_S, sTempPosY_S;
|
|
BOOLEAN fEndRenderRow = FALSE, fEndRenderCol = FALSE;
|
|
UINT16 usTileIndex;
|
|
INT16 sX, sY;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
|
|
|
|
// Begin Render Loop
|
|
sAnchorPosX_M = sStartPointX_M;
|
|
sAnchorPosY_M = sStartPointY_M;
|
|
sAnchorPosX_S = sStartPointX_S;
|
|
sAnchorPosY_S = sStartPointY_S;
|
|
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
do
|
|
{
|
|
|
|
fEndRenderRow = FALSE;
|
|
sTempPosX_M = sAnchorPosX_M;
|
|
sTempPosY_M = sAnchorPosY_M;
|
|
sTempPosX_S = sAnchorPosX_S;
|
|
sTempPosY_S = sAnchorPosY_S;
|
|
|
|
if(bXOddFlag > 0)
|
|
sTempPosX_S += 20;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
usTileIndex=FASTMAPROWCOLTOPOS( sTempPosY_M, sTempPosX_M );
|
|
|
|
if ( usTileIndex < GRIDSIZE )
|
|
{
|
|
sX = sTempPosX_S + ( WORLD_TILE_X / 2 ) - 5;
|
|
sY = sTempPosY_S + ( WORLD_TILE_Y / 2 ) - 5;
|
|
|
|
// Adjust for interface level
|
|
sY -= gpWorldLevelData[ usTileIndex ].sHeight;
|
|
sY += gsRenderHeight;
|
|
|
|
if (gsCoverValue[ usTileIndex] != 0x7F7F)
|
|
{
|
|
SetFont( SMALLCOMPFONT );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, gsVIEWPORT_END_Y, FALSE );
|
|
if (usTileIndex == gsBestCover)
|
|
{
|
|
SetFontForeground( FONT_MCOLOR_RED );
|
|
}
|
|
else if (gsCoverValue[ usTileIndex ] < 0)
|
|
{
|
|
SetFontForeground( FONT_MCOLOR_WHITE );
|
|
}
|
|
else
|
|
{
|
|
SetFontForeground( FONT_GRAY3 );
|
|
}
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", gsCoverValue[ usTileIndex ] );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
}
|
|
|
|
}
|
|
|
|
sTempPosX_S += 40;
|
|
sTempPosX_M ++;
|
|
sTempPosY_M --;
|
|
|
|
if ( sTempPosX_S >= sEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
sAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
sAnchorPosX_M ++;
|
|
}
|
|
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
sAnchorPosY_S += 10;
|
|
|
|
if ( sAnchorPosY_S >= sEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
}
|
|
|
|
|
|
void RenderGridNoVisibleDebugInfo( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS )
|
|
{
|
|
INT8 bXOddFlag = 0;
|
|
INT16 sAnchorPosX_M, sAnchorPosY_M;
|
|
INT16 sAnchorPosX_S, sAnchorPosY_S;
|
|
INT16 sTempPosX_M, sTempPosY_M;
|
|
INT16 sTempPosX_S, sTempPosY_S;
|
|
BOOLEAN fEndRenderRow = FALSE, fEndRenderCol = FALSE;
|
|
UINT16 usTileIndex;
|
|
INT16 sX, sY;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
|
|
|
|
// Begin Render Loop
|
|
sAnchorPosX_M = sStartPointX_M;
|
|
sAnchorPosY_M = sStartPointY_M;
|
|
sAnchorPosX_S = sStartPointX_S;
|
|
sAnchorPosY_S = sStartPointY_S;
|
|
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
do
|
|
{
|
|
|
|
fEndRenderRow = FALSE;
|
|
sTempPosX_M = sAnchorPosX_M;
|
|
sTempPosY_M = sAnchorPosY_M;
|
|
sTempPosX_S = sAnchorPosX_S;
|
|
sTempPosY_S = sAnchorPosY_S;
|
|
|
|
if(bXOddFlag > 0)
|
|
sTempPosX_S += 20;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
usTileIndex=FASTMAPROWCOLTOPOS( sTempPosY_M, sTempPosX_M );
|
|
|
|
if ( usTileIndex < GRIDSIZE )
|
|
{
|
|
sX = sTempPosX_S + ( WORLD_TILE_X / 2 ) - 5;
|
|
sY = sTempPosY_S + ( WORLD_TILE_Y / 2 ) - 5;
|
|
|
|
// Adjust for interface level
|
|
sY -= gpWorldLevelData[ usTileIndex ].sHeight;
|
|
sY += gsRenderHeight;
|
|
|
|
SetFont( SMALLCOMPFONT );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, gsVIEWPORT_END_Y, FALSE );
|
|
|
|
if ( !GridNoOnVisibleWorldTile( usTileIndex ) )
|
|
{
|
|
SetFontForeground( FONT_MCOLOR_RED );
|
|
}
|
|
else
|
|
{
|
|
SetFontForeground( FONT_GRAY3 );
|
|
}
|
|
mprintf_buffer( pDestBuf, uiDestPitchBYTES, TINYFONT1, sX, sY , L"%d", usTileIndex );
|
|
SetFontDestBuffer( FRAME_BUFFER , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
|
|
|
}
|
|
|
|
sTempPosX_S += 40;
|
|
sTempPosX_M ++;
|
|
sTempPosY_M --;
|
|
|
|
if ( sTempPosX_S >= sEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
sAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
sAnchorPosX_M ++;
|
|
}
|
|
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
sAnchorPosY_S += 10;
|
|
|
|
if ( sAnchorPosY_S >= sEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
void ExamineZBufferRect( INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom)
|
|
{
|
|
CalcRenderParameters( sLeft, sTop, sRight, sBottom );
|
|
|
|
ExamineZBufferForHiddenTiles( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
|
|
}
|
|
|
|
|
|
void ExamineZBufferForHiddenTiles( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS )
|
|
{
|
|
INT8 bXOddFlag = 0;
|
|
INT16 sAnchorPosX_M, sAnchorPosY_M;
|
|
INT16 sAnchorPosX_S, sAnchorPosY_S;
|
|
INT16 sTempPosX_M, sTempPosY_M;
|
|
INT16 sTempPosX_S, sTempPosY_S;
|
|
BOOLEAN fEndRenderRow = FALSE, fEndRenderCol = FALSE;
|
|
UINT16 usTileIndex;
|
|
INT16 sX, sY, sWorldX, sZLevel;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
TILE_ELEMENT *TileElem;
|
|
INT8 bBlitClipVal;
|
|
LEVELNODE *pObject;
|
|
|
|
|
|
// Begin Render Loop
|
|
sAnchorPosX_M = sStartPointX_M;
|
|
sAnchorPosY_M = sStartPointY_M;
|
|
sAnchorPosX_S = sStartPointX_S;
|
|
sAnchorPosY_S = sStartPointY_S;
|
|
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
|
|
// Get VObject for firt land peice!
|
|
TileElem = &(gTileDatabase[ FIRSTTEXTURE1 ] );
|
|
|
|
|
|
do
|
|
{
|
|
|
|
fEndRenderRow = FALSE;
|
|
sTempPosX_M = sAnchorPosX_M;
|
|
sTempPosY_M = sAnchorPosY_M;
|
|
sTempPosX_S = sAnchorPosX_S;
|
|
sTempPosY_S = sAnchorPosY_S;
|
|
|
|
if(bXOddFlag > 0)
|
|
sTempPosX_S += 20;
|
|
|
|
|
|
do
|
|
{
|
|
|
|
usTileIndex=FASTMAPROWCOLTOPOS( sTempPosY_M, sTempPosX_M );
|
|
|
|
if ( usTileIndex < GRIDSIZE )
|
|
{
|
|
// ATE: Don;t let any vehicle sit here....
|
|
if ( FindStructure( usTileIndex, ( STRUCTURE_MOBILE ) ) )
|
|
{
|
|
// Continue...
|
|
goto ENDOFLOOP;
|
|
}
|
|
|
|
sX = sTempPosX_S;
|
|
sY = sTempPosY_S - gpWorldLevelData[usTileIndex].sHeight;
|
|
|
|
// Adjust for interface level
|
|
sY += gsRenderHeight;
|
|
|
|
// Caluluate zvalue
|
|
// Look for anything less than struct layer!
|
|
GetWorldXYAbsoluteScreenXY( sTempPosX_M, sTempPosY_M, &sWorldX, &sZLevel);
|
|
|
|
sZLevel += gsRenderHeight;
|
|
|
|
sZLevel=(sZLevel*Z_SUBLAYERS)+STRUCT_Z_LEVEL;
|
|
|
|
if ( gpWorldLevelData[usTileIndex].uiFlags & MAPELEMENT_REEVALUATE_REDUNDENCY )
|
|
{
|
|
bBlitClipVal = BltIsClippedOrOffScreen(TileElem->hTileSurface, sX, sY, TileElem->usRegionIndex, &gClippingRect);
|
|
|
|
if ( bBlitClipVal == FALSE )
|
|
{
|
|
// Set flag to not evaluate again!
|
|
gpWorldLevelData[usTileIndex].uiFlags &= (~MAPELEMENT_REEVALUATE_REDUNDENCY );
|
|
|
|
// OK, first do some rules with exceptions
|
|
// Don't let this happen for roads!
|
|
pObject = gpWorldLevelData[usTileIndex ].pObjectHead;
|
|
|
|
if ( IsTileRedundent( gpZBuffer, sZLevel, TileElem->hTileSurface, sX, sY, TileElem->usRegionIndex ) )
|
|
{
|
|
// Mark in the world!
|
|
gpWorldLevelData[ usTileIndex ].uiFlags |= MAPELEMENT_REDUNDENT;
|
|
}
|
|
else
|
|
{
|
|
// Un Mark in the world!
|
|
gpWorldLevelData[ usTileIndex ].uiFlags &= (~MAPELEMENT_REDUNDENT);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
ENDOFLOOP:
|
|
|
|
sTempPosX_S += 40;
|
|
sTempPosX_M ++;
|
|
sTempPosY_M --;
|
|
|
|
if ( sTempPosX_S >= sEndXS )
|
|
{
|
|
fEndRenderRow = TRUE;
|
|
}
|
|
|
|
} while( !fEndRenderRow );
|
|
|
|
if ( bXOddFlag > 0 )
|
|
{
|
|
sAnchorPosY_M ++;
|
|
}
|
|
else
|
|
{
|
|
sAnchorPosX_M ++;
|
|
}
|
|
|
|
|
|
bXOddFlag = !bXOddFlag;
|
|
sAnchorPosY_S += 10;
|
|
|
|
if ( sAnchorPosY_S >= sEndYS )
|
|
{
|
|
fEndRenderCol = TRUE;
|
|
}
|
|
|
|
}
|
|
while( !fEndRenderCol );
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
|
|
{
|
|
INT16 sTempPosX_W, sTempPosY_W;
|
|
INT16 sRenderCenterX_W, sRenderCenterY_W;
|
|
INT16 sOffsetX_W, sOffsetY_W, sOffsetX_S, sOffsetY_S;
|
|
|
|
gOldClipRect = gClippingRect;
|
|
|
|
// Set new clipped rect
|
|
gClippingRect.iLeft = __max( gsVIEWPORT_START_X, sLeft);
|
|
gClippingRect.iRight = __min( gsVIEWPORT_END_X, sRight);
|
|
gClippingRect.iTop = __max( gsVIEWPORT_WINDOW_START_Y, sTop);
|
|
gClippingRect.iBottom = __min(gsVIEWPORT_WINDOW_END_Y, sBottom);
|
|
|
|
gsEndXS = sRight + VIEWPORT_XOFFSET_S;
|
|
gsEndYS = sBottom + VIEWPORT_YOFFSET_S;
|
|
|
|
sRenderCenterX_W = gsRenderCenterX;
|
|
sRenderCenterY_W = gsRenderCenterY;
|
|
|
|
// STEP THREE - determine starting point in world coords
|
|
// a) Determine where in screen coords to start rendering
|
|
gsStartPointX_S = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) - (sLeft - VIEWPORT_XOFFSET_S);
|
|
gsStartPointY_S = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) - (sTop - VIEWPORT_YOFFSET_S);
|
|
|
|
|
|
// b) Convert these distances into world distances
|
|
FromScreenToCellCoordinates( gsStartPointX_S, gsStartPointY_S, &sTempPosX_W, &sTempPosY_W );
|
|
|
|
// c) World start point is Render center minus this distance
|
|
gsStartPointX_W = sRenderCenterX_W - sTempPosX_W;
|
|
gsStartPointY_W = sRenderCenterY_W - sTempPosY_W;
|
|
|
|
// NOTE: Increase X map value by 1 tile to offset where on screen we are...
|
|
if ( gsStartPointX_W > 0 )
|
|
gsStartPointX_W += CELL_X_SIZE;
|
|
|
|
// d) screen start point is screen distances minus screen center
|
|
gsStartPointX_S = sLeft - VIEWPORT_XOFFSET_S;
|
|
gsStartPointY_S = sTop - VIEWPORT_YOFFSET_S;
|
|
|
|
// STEP FOUR - Determine Start block
|
|
// a) Find start block
|
|
gsStartPointX_M = ( gsStartPointX_W ) / CELL_X_SIZE;
|
|
gsStartPointY_M = ( gsStartPointY_W ) / CELL_Y_SIZE;
|
|
|
|
// STEP 5 - Determine Deltas for center and find screen values
|
|
//Make sure these coordinates are multiples of scroll steps
|
|
sOffsetX_W = abs( gsStartPointX_W ) - ( abs( ( gsStartPointX_M * CELL_X_SIZE ) ) );
|
|
sOffsetY_W = abs( gsStartPointY_W ) - ( abs( ( gsStartPointY_M * CELL_Y_SIZE ) ) );
|
|
|
|
FromCellToScreenCoordinates( sOffsetX_W, sOffsetY_W, &sOffsetX_S, &sOffsetY_S );
|
|
|
|
if ( gsStartPointY_W < 0 )
|
|
{
|
|
gsStartPointY_S += 0;//(sOffsetY_S/2);
|
|
}
|
|
else
|
|
{
|
|
gsStartPointY_S -= sOffsetY_S;
|
|
}
|
|
gsStartPointX_S -= sOffsetX_S;
|
|
|
|
|
|
// Set globals for render offset
|
|
if ( gsRenderWorldOffsetX == -1 )
|
|
{
|
|
gsRenderWorldOffsetX = sOffsetX_S;
|
|
}
|
|
|
|
if ( gsRenderWorldOffsetY == -1 )
|
|
{
|
|
gsRenderWorldOffsetY = sOffsetY_S;
|
|
}
|
|
|
|
/////////////////////////////////////////
|
|
//ATE: CALCULATE LARGER OFFSET VALUES
|
|
gsLEndXS = sRight + LARGER_VIEWPORT_XOFFSET_S;
|
|
gsLEndYS = sBottom + LARGER_VIEWPORT_YOFFSET_S;
|
|
|
|
// STEP THREE - determine starting point in world coords
|
|
// a) Determine where in screen coords to start rendering
|
|
gsLStartPointX_S = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) - (sLeft - LARGER_VIEWPORT_XOFFSET_S);
|
|
gsLStartPointY_S = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) - (sTop - LARGER_VIEWPORT_YOFFSET_S);
|
|
|
|
|
|
// b) Convert these distances into world distances
|
|
FromScreenToCellCoordinates( gsLStartPointX_S, gsLStartPointY_S, &sTempPosX_W, &sTempPosY_W );
|
|
|
|
// c) World start point is Render center minus this distance
|
|
gsLStartPointX_W = sRenderCenterX_W - sTempPosX_W;
|
|
gsLStartPointY_W = sRenderCenterY_W - sTempPosY_W;
|
|
|
|
// NOTE: Increase X map value by 1 tile to offset where on screen we are...
|
|
if ( gsLStartPointX_W > 0 )
|
|
gsLStartPointX_W += CELL_X_SIZE;
|
|
|
|
// d) screen start point is screen distances minus screen center
|
|
gsLStartPointX_S = sLeft - LARGER_VIEWPORT_XOFFSET_S;
|
|
gsLStartPointY_S = sTop - LARGER_VIEWPORT_YOFFSET_S;
|
|
|
|
// STEP FOUR - Determine Start block
|
|
// a) Find start block
|
|
gsLStartPointX_M = ( gsLStartPointX_W ) / CELL_X_SIZE;
|
|
gsLStartPointY_M = ( gsLStartPointY_W ) / CELL_Y_SIZE;
|
|
|
|
// Adjust starting screen coordinates
|
|
gsLStartPointX_S -= sOffsetX_S;
|
|
|
|
if ( gsLStartPointY_W < 0 )
|
|
{
|
|
gsLStartPointY_S += 0;
|
|
gsLStartPointX_S -= 20;
|
|
}
|
|
else
|
|
{
|
|
gsLStartPointY_S -= sOffsetY_S;
|
|
}
|
|
|
|
}
|
|
|
|
void ResetRenderParameters( )
|
|
{
|
|
// Restore clipping rect
|
|
gClippingRect = gOldClipRect;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN Zero8BPPDataTo16BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
|
|
{
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth;
|
|
UINT8 *SrcPtr, *DestPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY;
|
|
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
// Validations
|
|
CHECKF( iTempX >= 0 );
|
|
CHECKF( iTempY >= 0 );
|
|
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
|
|
LineSkip=(uiDestPitchBYTES-(usWidth*2));
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
xor ecx, ecx
|
|
|
|
BlitDispatch:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz BlitDoneLine
|
|
|
|
//BlitNonTransLoop:
|
|
|
|
clc
|
|
rcr cl, 1
|
|
jnc BlitNTL2
|
|
|
|
mov [edi], ax
|
|
|
|
inc esi
|
|
add edi, 2
|
|
|
|
BlitNTL2:
|
|
clc
|
|
rcr cl, 1
|
|
jnc BlitNTL3
|
|
|
|
mov [edi], ax
|
|
|
|
mov [edi+2], ax
|
|
|
|
add esi, 2
|
|
add edi, 4
|
|
|
|
BlitNTL3:
|
|
|
|
or cl, cl
|
|
jz BlitDispatch
|
|
|
|
xor ebx, ebx
|
|
|
|
BlitNTL4:
|
|
|
|
mov [edi], ax
|
|
|
|
mov [edi+2], ax
|
|
|
|
mov [edi+4], ax
|
|
|
|
mov [edi+6], ax
|
|
|
|
add esi, 4
|
|
add edi, 8
|
|
dec cl
|
|
jnz BlitNTL4
|
|
|
|
jmp BlitDispatch
|
|
|
|
BlitTransparent:
|
|
|
|
and ecx, 07fH
|
|
// shl ecx, 1
|
|
add ecx, ecx
|
|
add edi, ecx
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDoneLine:
|
|
|
|
dec usHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
BOOLEAN Blt8BPPDataTo16BPPBufferTransInvZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
|
|
{
|
|
UINT16 *p16BPPPalette;
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth;
|
|
UINT8 *SrcPtr, *DestPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY;
|
|
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
Assert( pBuffer != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
// Validations
|
|
CHECKF( iTempX >= 0 );
|
|
CHECKF( iTempY >= 0 );
|
|
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
|
|
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
|
|
p16BPPPalette = hSrcVObject->pShadeCurrent;
|
|
LineSkip=(uiDestPitchBYTES-(usWidth*2));
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edi, DestPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
BlitDispatch:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz BlitDoneLine
|
|
|
|
//BlitNonTransLoop:
|
|
|
|
xor eax, eax
|
|
|
|
BlitNTL4:
|
|
|
|
mov ax, usZValue
|
|
cmp ax, [ebx]
|
|
jne BlitNTL5
|
|
|
|
//mov [ebx], ax
|
|
|
|
xor ah, ah
|
|
mov al, [esi]
|
|
mov ax, [edx+eax*2]
|
|
mov [edi], ax
|
|
|
|
BlitNTL5:
|
|
inc esi
|
|
inc edi
|
|
inc ebx
|
|
inc edi
|
|
inc ebx
|
|
|
|
dec cl
|
|
jnz BlitNTL4
|
|
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitTransparent:
|
|
|
|
and ecx, 07fH
|
|
// shl ecx, 1
|
|
add ecx, ecx
|
|
add edi, ecx
|
|
add ebx, ecx
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDoneLine:
|
|
|
|
dec usHeight
|
|
jz BlitDone
|
|
add edi, LineSkip
|
|
add ebx, LineSkip
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN IsTileRedundent( UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
|
|
{
|
|
UINT16 *p16BPPPalette;
|
|
UINT32 uiOffset;
|
|
UINT32 usHeight, usWidth;
|
|
UINT8 *SrcPtr, *ZPtr;
|
|
UINT32 LineSkip;
|
|
ETRLEObject *pTrav;
|
|
INT32 iTempX, iTempY;
|
|
BOOLEAN fHidden = TRUE;
|
|
|
|
|
|
// Assertions
|
|
Assert( hSrcVObject != NULL );
|
|
|
|
// Get Offsets from Index into structure
|
|
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
|
|
usHeight = (UINT32)pTrav->usHeight;
|
|
usWidth = (UINT32)pTrav->usWidth;
|
|
uiOffset = pTrav->uiDataOffset;
|
|
|
|
// Add to start position of dest buffer
|
|
iTempX = iX + pTrav->sOffsetX;
|
|
iTempY = iY + pTrav->sOffsetY;
|
|
|
|
// Validations
|
|
CHECKF( iTempX >= 0 );
|
|
CHECKF( iTempY >= 0 );
|
|
|
|
|
|
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
|
|
ZPtr = (UINT8 *)pZBuffer + (2280*iTempY) + (iTempX*2);
|
|
p16BPPPalette = hSrcVObject->pShadeCurrent;
|
|
LineSkip=(2280-(usWidth*2));
|
|
|
|
__asm {
|
|
|
|
mov esi, SrcPtr
|
|
mov edx, p16BPPPalette
|
|
xor eax, eax
|
|
mov ebx, ZPtr
|
|
xor ecx, ecx
|
|
|
|
BlitDispatch:
|
|
|
|
mov cl, [esi]
|
|
inc esi
|
|
or cl, cl
|
|
js BlitTransparent
|
|
jz BlitDoneLine
|
|
|
|
//BlitNonTransLoop:
|
|
|
|
xor eax, eax
|
|
|
|
BlitNTL4:
|
|
|
|
mov ax, usZValue
|
|
cmp ax, [ebx]
|
|
jle BlitNTL5
|
|
|
|
|
|
// Set false, flag
|
|
mov fHidden, 0
|
|
jmp BlitDone
|
|
|
|
|
|
BlitNTL5:
|
|
inc esi
|
|
inc ebx
|
|
inc ebx
|
|
|
|
dec cl
|
|
jnz BlitNTL4
|
|
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitTransparent:
|
|
|
|
and ecx, 07fH
|
|
// shl ecx, 1
|
|
add ecx, ecx
|
|
add ebx, ecx
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDoneLine:
|
|
|
|
dec usHeight
|
|
jz BlitDone
|
|
add ebx, LineSkip
|
|
jmp BlitDispatch
|
|
|
|
|
|
BlitDone:
|
|
}
|
|
|
|
return(fHidden);
|
|
|
|
}
|
|
|
|
void SetMercGlowFast( )
|
|
{
|
|
//gpGlowFramePointer = gsFastGlowFrames;
|
|
}
|
|
|
|
void SetMercGlowNormal( )
|
|
{
|
|
gpGlowFramePointer = gsGlowFrames;
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_MOVING )
|
|
{
|
|
if ( sZOffsetY > 0 )
|
|
{
|
|
sZOffsetY++;
|
|
}
|
|
if ( sZOffsetX > 0 )
|
|
{
|
|
sZOffsetX++;
|
|
}
|
|
}
|
|
|
|
sZOffsetX = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetX;\
|
|
sZOffsetY = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetY;\
|
|
|
|
|
|
if ( ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) )\
|
|
{\
|
|
sZOffsetX = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetX;\
|
|
sZOffsetY = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetY;\
|
|
\
|
|
GetMapXYWorldY( sMapX + sZOffsetX, sMapY + sZOffsetY, sWorldY );\
|
|
}\
|
|
else
|
|
|
|
#endif
|
|
|
|
|
|
void SetRenderCenter( INT16 sNewX, INT16 sNewY )
|
|
{
|
|
if ( gfIgnoreScrolling == 1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Apply these new coordinates to the renderer!
|
|
ApplyScrolling( sNewX, sNewY, TRUE , FALSE );
|
|
|
|
// Set flag to ignore scrolling this frame
|
|
gfIgnoreScrollDueToCenterAdjust = TRUE;
|
|
|
|
// Set full render flag!
|
|
// DIRTY THE WORLD!
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
|
|
gfPlotNewMovement = TRUE;
|
|
|
|
if ( gfScrollPending == TRUE )
|
|
{
|
|
// Do a complete rebuild!
|
|
gfScrollPending = FALSE;
|
|
|
|
// Restore Interface!
|
|
RestoreInterface( );
|
|
|
|
// Delete Topmost blitters saved areas
|
|
DeleteVideoOverlaysArea( );
|
|
|
|
}
|
|
|
|
gfScrollInertia = FALSE;
|
|
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void RenderFOVDebug( )
|
|
{
|
|
RenderFOVDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
|
|
void RenderCoverDebug( )
|
|
{
|
|
RenderCoverDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
|
|
void RenderGridNoVisibleDebug( )
|
|
{
|
|
RenderGridNoVisibleDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS );
|
|
}
|
|
|
|
#endif
|