ScummVM API documentation
line_of_sight.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1999-2000 Revolution Software Ltd.
9 * This code is based on source code created by Revolution Software,
10 * used with permission.
11 *
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 *
25 */
26
27#ifndef ICB_LINEOFSIGHT_H_INCLUDED
28#define ICB_LINEOFSIGHT_H_INCLUDED
29
30#include "engines/icb/p4.h"
31#include "engines/icb/debug.h"
32#include "engines/icb/event_list.h"
33#include "engines/icb/event_manager.h"
34#include "engines/icb/common/px_linkeddatafile.h"
35#include "engines/icb/common/px_route_barriers.h"
36#include "engines/icb/common/px_string.h"
37#include "engines/icb/common/px_3drealpoint.h"
38
39namespace ICB {
40
41#define LOS_LOG "LOS_log.txt"
42
43// This sets the default field-of-view for mega characters.
44#define LOS_DEFAULT_MEGA_FIELD_OF_VIEW 180
45
46// This sets the default view height for mega characters (+/- this linear distance in cm).
47// BIG NOTE: This value must be LESS than the difference between the crouched height and the normal eye-height,
48// otherwise LOS will always return false when one mega is crouched and another is standing.
49#define LOS_DEFAULT_OBJECT_HEIGHT_OF_VIEW (100 * REAL_ONE)
50
51// This sets how far an object can see by default.
52#define LOS_DEFAULT_OBJECT_SEEING_DISTANCE 2000
53
54// This defines the default number of subscribers to process per cycle of the LOS logic.
55#define LOS_DEFAULT_SUBSCRIBERS_PER_CYCLE 3
56
57// This is the size of the 2D and 1D tables.
58#define LOS_1D_SIZE (MAX_session_objects)
59#define LOS_2D_ROWSIZE_PACKED (MAX_session_objects / 8)
60#define LOS_2D_SIZE_PACKED (MAX_session_objects * LOS_2D_ROWSIZE_PACKED)
61
62// Module to calculate which objects (voxel characters and other objects) can see which other objects. The information
63// is used to generate events, which are given to the event manager, so it can decide what needs to hear about the change.
65public:
66 // Definitions used by this class.
67 enum { ACTOR_EYE_HEIGHT = 160 };
68 enum { ACTOR_CROUCHED_HEIGHT = 61 };
69 enum ActorEyeMode { USE_OBJECT_VALUE = 0, FORCE_EYE_HEIGHT, FORCE_CROUCHED_HEIGHT };
70
71 // Default constructor and destructor.
72 inline _line_of_sight();
73 inline ~_line_of_sight();
74
75 // This attaches this object to its data files and sets other start-up values.
76 void Initialise();
77
78 // These add and remove objects from the service.
79 void Subscribe(uint32 nObserverID, uint32 nTargetID);
80 void UnSubscribe(uint32 nObserverID, uint32 nTargetID);
81
82 // These allow an object to be temporarily suspended in the LOS engine, but the objects they
83 // are registered to see are remembered for when the suspension is removed.
84 void Suspend(uint32 nObserverID);
85 inline void Unsuspend(uint32 nObserverID);
86
87 // These two turn off the whole of line-of-sight processing for everybody. All the registrations are kept
88 // though, so it can resume where it left off.
89 void SwitchOff();
90 void SwitchOn() { m_bSwitchedOn = TRUE8; }
91
92 // The engine actually calls this function instead of Cycle() directly, so that the amount of time
93 // spent in line-of-sight calculation can be controlled.
94 void DutyCycle();
95
96 // This function allows the how many subscribers to do per cycle
97 inline void SetDutyCycle(uint32 nSubsPerCycle) { m_nSubsPerCycle = nSubsPerCycle; }
98
99 // This allows the field-of-view to be changed from the default 180 for a mega character.
100 void SetFieldOfView(uint32 nID, uint32 nFieldOfView);
101
102 // This allows the range an object sees to be changed from the default.
103 void SetSightRange(uint32 nID, uint32 nRange);
104
105 // This allows the height range an object sees to be changed from the default.
106 void SetSightHeight(uint32 nID, uint32 nHeight);
107
108 // This sets whether or not an object can see in the dark.
109 inline void SetCanSeeInDarkFlag(uint32 nID, bool8 bState);
110
111 // This sets whether or not a mega is always seen regardless of shadows or not.
112 inline void SetNeverInShadowFlag(uint32 nID, bool8 bState);
113
114 // This turns off shadow-handling for the whole LOS engine.
115 inline void ShadowsOnOff(bool8 bState) { m_bHandleShadows = bState; }
116
117 // This checks line-of-sight between two objects, accounting for field-of-view if observer is an actor,
118 bool8 ObjectToObject(uint32 nObserverID, uint32 nTargetID, eBarrierRayType eRayType, bool8 bCanSeeUs, ActorEyeMode eEyeMode, bool8 bOverrideHeightLimit = FALSE8);
119
120 // This checks line-of-sight using the current truth table values and so is fast.
121 inline bool8 LineOfSight(uint32 nObserverID, uint32 nTargetID);
122
123 // And these two return extra information after a call to ObjectToObject().
124 const px3DRealPoint GetLastImpactPoint() const { return (m_oImpactPoint); }
125 eBarrierLogicValue GetLastImpactType() const { return (m_eImpactType); }
126
127 // This allows other classes to get at the barrier slices (the Remora needs this).
128 LinkedDataFile *GetSlicesPointer() const { return (m_pyLOSData); }
129
130 bool8 FailingOnHeight() const { return (m_bFailingOnHeight); }
131
132private:
133 LinkedDataFile *m_pyLOSData; // Pointer to the loaded line-of-sight data file.
134 uint32 m_nSubsPerCycle; // How many subscribers to process per cycle.
135 uint32 m_nFirstSubscriber; // Number of first subscriber to process
136 uint32 m_nNumObjects; // Number of subscribers to this service.
137 uint32 m_nTotalCurrentSubscribers; // Total number of current subscribers to this service.
138 uint32 m_pnFieldOfView[LOS_1D_SIZE]; // Current field-of-view for each mega.
139 uint32 m_pnSeeingDistance[LOS_1D_SIZE]; // Maximum distance an object can see.
140 PXreal m_pfHeightOfView[LOS_1D_SIZE]; // Height restriction on view.
141 int32 m_pnSubscribeNum[LOS_1D_SIZE]; // How many times a game object has subscribed.
142 uint8 m_pnTable[LOS_2D_SIZE_PACKED]; // The truth-table of who can see who.
143 uint8 m_pnSubscribers[LOS_2D_SIZE_PACKED]; // Housekeeping table of current subscribers to the service.
144 bool8 m_pbSuspended[LOS_1D_SIZE]; // If true, the object has been temporarily suspended.
145 bool8 m_pbCanSeeInDark[LOS_1D_SIZE]; // Housekeeping table of objects that should ignore shadows.
146 bool8 m_pbIgnoreShadows[LOS_1D_SIZE]; // Table of megas that are always seen regardless of shadows.
147 px3DRealPoint m_oImpactPoint; // Holds impact point from last call to ObjectToObject().
148 eBarrierLogicValue m_eImpactType; // Holds type of impact from last call to ObjectToObject().
149 bool8 m_bSwitchedOn; // Flag that allows LOS processing to be suspended.
150 bool8 m_bFailingOnHeight; // Debug flag that gets set when a barrier height check fails.
151 bool8 m_bHandleShadows; // Turns shadow handling on/off.
152 uint8 m_nPad;
153
154 // Here I block the use of the default '='.
156 void operator=(const _line_of_sight &) {}
157
158 // Functions used internally by this class.
159 void WhatSeesWhat();
160
161 bool8 InFieldOfView(PXreal fLookingX, PXreal fLookingZ, PXfloat fLookingDirection, PXreal fObservedX, PXreal fObservedZ, uint32 nFieldOfView) const;
162
163 inline void SetPackedBit(uint8 *pnArray, uint32 i, uint32 j, bool8 bValue);
164 inline bool8 GetPackedBit(uint8 *pnArray, uint32 i, uint32 j) const;
165};
166
167extern _line_of_sight *g_oLineOfSight;
168
169inline _line_of_sight::_line_of_sight() {
170 m_bSwitchedOn = TRUE8;
171 m_nSubsPerCycle = LOS_DEFAULT_SUBSCRIBERS_PER_CYCLE;
172 m_nFirstSubscriber = 0;
173 m_pyLOSData = NULL;
174 m_nNumObjects = 0;
175 m_nTotalCurrentSubscribers = 0;
176 m_bHandleShadows = TRUE8;
177 m_nPad = 0;
178}
179
180inline _line_of_sight::~_line_of_sight() {
181 m_pyLOSData = NULL;
182 m_nNumObjects = 0;
183
184 Zdebug("Destroyed line-of-sight object");
185}
186
187inline void _line_of_sight::Unsuspend(uint32 nObserverID) {
188 // Set the flag for the object.
189 m_pbSuspended[nObserverID] = FALSE8;
190}
191
192inline void _line_of_sight::SetCanSeeInDarkFlag(uint32 nID, bool8 bState) {
193 // Set the flag for the object.
194 m_pbCanSeeInDark[nID] = bState;
195}
196
197inline void _line_of_sight::SetNeverInShadowFlag(uint32 nID, bool8 bState) {
198 // Set the flag for the object.
199 m_pbIgnoreShadows[nID] = bState;
200}
201
202inline bool8 _line_of_sight::LineOfSight(uint32 nObserverID, uint32 nTargetID) { return (GetPackedBit(m_pnTable, nObserverID, nTargetID)); }
203
204inline void _line_of_sight::SwitchOff() {
205 m_bSwitchedOn = FALSE8;
206
207 memset((uint8 *)m_pnTable, 0, (size_t)(LOS_2D_SIZE_PACKED * sizeof(uint8)));
208}
209
210inline void _line_of_sight::SetPackedBit(uint8 *pnArray, uint32 i, uint32 j, bool8 bValue) {
211 uint32 nJIndex = j >> 3;
212 uint32 nJRemainder = (j & 0x00000007);
213
214 if (bValue)
215 pnArray[i * LOS_2D_ROWSIZE_PACKED + nJIndex] |= (uint8)(1 << nJRemainder);
216 else
217 pnArray[i * LOS_2D_ROWSIZE_PACKED + nJIndex] &= (uint8)(~(1 << nJRemainder));
218}
219
220inline bool8 _line_of_sight::GetPackedBit(uint8 *pnArray, uint32 i, uint32 j) const {
221 uint32 nJIndex = j >> 3;
222 uint32 nJRemainder = (j & 0x00000007);
223
224 if ((pnArray[i * LOS_2D_ROWSIZE_PACKED + nJIndex] & (uint8)(1 << nJRemainder)) != 0)
225 return (TRUE8);
226 else
227 return (FALSE8);
228}
229
230} // End of namespace ICB
231
232#endif // #if !defined( LINEOFSIGHT_H_INCLUDED )
Definition: line_of_sight.h:64
Definition: px_3drealpoint.h:45
Definition: px_linkeddatafile.h:53