-
Notifications
You must be signed in to change notification settings - Fork 0
/
FirstPersonView.ash
158 lines (143 loc) · 6.69 KB
/
FirstPersonView.ash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// TODO: rewrite / adjust following large commentary, as the
// data representation was changed for this project!!
// TODO: explain and give image of a single cell and its walls
// CellViewSchema describes location of drawn tiles on screen, in screen coordinates.
//
// Let's assume the player's "eye" can see number of map cells around itself,
// then we think of the cells's distance along the forward axis as of VIEW ROW
// and cell's distance along the side axis as of VIEW COLUMN.
// View rows begin at 0 and go up, view columns originate at 0 and go down and up
// (left and right) symmetrically. Player's eye is at 0,0.
// E.g.:
// cols
// -2 -1 0 +1 +2
// 3 x x x x x
// rows 2 x x x x x
// 1 x x x x x
// 0 x x x
// ^
// E
//
//
// Particular VIEW ROW and VIEW COLUMN give us a VIEW CELL.
// For each visible cell the schema defines a screen rectangle of every possible part
// of the map object: front wall, side walls, floor and ceiling.
// "Front wall" is the one facing player, "back wall" is the far wall of the cell
// (latter may be ignored if your game does not feature transparent walls),
// left and right walls are cell's side walls that are further to left or to right
// from cell's center, relative to how player sees the cell.
// Note that for side columns you may define only one of the side walls (again, this
// depends on whether you feature transparent walls).
// E.g.:
// _ ........ ........ ........ _
// _ -__|______ /|________|\ ______|__- _
// | |......|.|........|.|......| |
// | _ - | / \ | - _ |
// |-___________|/__________\|___________-|
//
// -1 0 +1
//
// Here cell at 0 should have at least: front wall, floor and ceiling defined.
// Cell at -1 should have front wall and right wall defined (+ floor & ceiling)
// and cell at +1 needs front wall and left wall defined (+ floor & ceiling).
// Other walls are optional.
//
// More tile definitions could be added if necessary (if their positions cannot be
// easily derived from ones above).
//
// Cell rows and columns limits
#define CELLVIEW_MAX_CELL_ROWS (6)
#define CELLVIEW_MAX_CELL_COLS (11)
#define CELLVIEW_MAX_CELL_SPACE (CELLVIEW_MAX_ROWS * CELLVIEW_MAX_COLS)
// Cell vertices limits
// Strips of vertices always have +1 element more than cells
#define CELLVIEW_MAX_VX_ROWS (CELLVIEW_MAX_CELL_ROWS + 1)
#define CELLVIEW_MAX_VX_COLS (CELLVIEW_MAX_CELL_COLS + 1)
// TODO: separate constants for left and right side walls,
// may be necessary if we support "fences" between passable cells
enum CellViewTile {
eCVTile_Floor = 0,
eCVTile_Ceil,
eCVTile_Front,
eCVTile_Side, // side wall (left or right, depending on cell pos)
eCVTile_Base, // cell-object, occupying whole cell
eCVTile_Object, // placeholder for "any object in cell"
eCVTileNum
};
// Vertex positions!!
struct CellViewStrip {
bool Valid;
int Y1, Y2;
int X[CELLVIEW_MAX_VX_COLS];
};
struct CellViewSchema {
writeprotected int Width; // viewport width
writeprotected int Height; // viewport height
writeprotected int CellRowCount; // number of near->far cells
writeprotected int CellColCount; // number of left->right cells
writeprotected int CellColMiddle; // middle cell column
writeprotected int VxRowCount; // number of near->far grid lines
writeprotected int VxColCount; // number of left->right grid lines
// scale down factors for entities (items, objects and mobs)
writeprotected float BaseScale; // scale factor at the starting cell
writeprotected float RowScaling; // scale factor, applied per each row of cells
writeprotected float ColScaling; // scale factor, applied per each column of cells
// These are vertex (grid) positions!!
writeprotected CellViewStrip Strips[CELLVIEW_MAX_VX_ROWS];
// Scaling factors per cell
writeprotected float CellScaling[CELLVIEW_MAX_CELL_ROWS, CELLVIEW_MAX_CELL_COLS];
// Cell's geometric centers, for easier aligning of objects
writeprotected int CellCenterX[CELLVIEW_MAX_CELL_ROWS, CELLVIEW_MAX_CELL_COLS];
writeprotected int CellCenterY[CELLVIEW_MAX_CELL_ROWS, CELLVIEW_MAX_CELL_COLS];
// Setup basic schema properties
import void SetView(int width, int height, int row_count, int col_count);
// Generate x-uniform strip
import void SetUniformStrip(int vx_row, int y1, int y2, int x_start, int u_width);
import void SetStrip(int vx_row, int y1, int y2, int x[]);
// Generate scaling factors for each cell
import void SetScaling(float base_scale, float row_scale, float col_scale);
// Generate any remaining data, this should be called last after configuring other things.
import void Finalize();
// Converts a relative position in object's local space to the
// cell view's row/cell pair
import Point *ObjectToCellView(int objx, int objy);
};
// Current grid view schema setup
import CellViewSchema CV_Schema;
// FirstPersonView class draws a pseudo-3D first person view of a map as if visible
// from the player's eyes.
struct FirstPersonView {
//
// Configuration
//
// Tells to draw walls half-height, helps testing level actors
import static void SetHalfWallMode(bool half_wall);
//
//
// Methods for drawing the helper grid on a surface
//
// Draws a rectangle around viewport
import static void DrawViewport(DrawingSurface* ds, int color);
// Draws a grid frame for testing purposes
import static void DrawGridFrame(DrawingSurface* ds, int cell_color, int wall_color);
//
// Methods for constructing the first person view using room overlays
//
// Generates required assets for the current level
import static void GenerateAssetsForLevel();
// Sets camera offset to add when constructing a scene using overlays
import static void SetCameraOffset(int camx, int camy);
import static void ConstructLocation(ObjectPosition *eye);
import static void ConstructCell(ObjectPosition *eye, int mapx, int mapy, int row, int col);
// Arranges the object (represented by overlay) in the first person view
import static void ConstructObject(ObjectPosition *eye, ObjectPosition *obj,
int view, int loop, int frame, bool directional, Overlay *over);
import protected static void ResetTileCache();
import protected static void DisplayWallTile(int row, int col, CellViewTile tile,
int tex_id , int frame_index = -1);
import protected static void HideWallTile(int row, int col, CellViewTile tile);
import protected static DynamicSprite *CreateWallSprite(int row, int col,
CellViewTile tile, int tex_id, int frame_index = -1);
import protected static void CreateWallTile(int row, int col, CellViewTile tile);
import protected static int CalcZorder(int row, int col, CellViewTile tile);
};