1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
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
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (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, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 *
26 */
27
28 #include "engines/icb/common/px_common.h"
29 #include "engines/icb/p4_generic.h"
30 #include "engines/icb/debug.h"
31 #include "engines/icb/mission.h"
32 #include "engines/icb/text.h"
33 #include "engines/icb/direct_input.h"
34 #include "engines/icb/global_objects.h"
35 #include "engines/icb/global_switches.h"
36 #include "engines/icb/surface_manager.h"
37 #include "engines/icb/stage_draw.h"
38 #include "engines/icb/actor.h"
39 #include "engines/icb/actor_pc.h"
40 #include "engines/icb/res_man.h"
41 #include "engines/icb/common/px_capri_maths.h"
42 #include "engines/icb/gfx/psx_anims.h"
43
44 namespace ICB {
45
46 void PolyStageDraw(SDactor *actors, uint32 actorQty);
47
Stage_draw_poly()48 void _game_session::Stage_draw_poly() {
49 // The actors to draw
50 SDactor actors[MAXIMUM_POTENTIAL_ON_SCREEN_ACTOR_QUANTITY];
51
52 // Get back which mega the actor could interact with
53 int32 sel_id = GetSelectedMegaId();
54
55 // Fill in the actors that need drawing an update thier positions
56 uint32 actorsToDraw = 0;
57 int32 id;
58 for (uint32 j = 0; j < number_of_voxel_ids; j++) {
59 // fetch the logic structure for the game object that has a voxel image to render
60 id = (int32)voxel_id_list[j];
61 _logic *log = logic_structs[id];
62
63 // Only clip by HITHER_PLANE, ActorDraw will clip image to film boundaries
64 if (Object_visible_to_camera(id)) {
65 g_mission->nActorsConsidered++;
66
67 bool8 result = TRUE8;
68 PXvector filmPosition;
69 PXWorldToFilm(log->mega->actor_xyz, set.GetCamera(), result, filmPosition);
70
71 if (filmPosition.z < -g_actor_hither_plane) {
72 VECTOR v;
73 v.vx = (int32)log->mega->actor_xyz.x;
74 v.vy = (int32)log->mega->actor_xyz.y;
75 v.vz = (int32)log->mega->actor_xyz.z;
76
77 SVECTOR orient;
78 orient.vx = 0;
79 orient.vy = 0;
80 orient.vz = 0;
81
82 // Ignore characters who are off screen
83 if (QuickActorCull((psxCamera *)&MSS.GetCamera(), &v, &orient) == 1)
84 continue;
85
86 SDactor &thisActor = actors[actorsToDraw];
87
88 // do a high level anim file existence check!
89 if (!log->voxel_info->IsAnimTable(log->cur_anim_type))
90 Fatal_error("Illegal anim type [%s %s %s] for [%s]", master_anim_name_table[log->cur_anim_type].name, log->mega->chr_name,
91 log->mega->anim_set, log->GetName());
92
93 thisActor.anim_name =
94 log->voxel_info->anim_name[log->cur_anim_type]; // this should do the trick now that anim mega set.cpp sets names correct for polygons...
95
96 // setup act element
97
98 thisActor.frame = log->anim_pc;
99
100 psxActor &act = thisActor.psx_actor;
101
102 uint32 hash1 = NULL_HASH;
103 uint32 hash2 = NULL_HASH;
104
105 PXanim_PSX *pAnim = (PXanim_PSX *)rs_anims->Res_open(log->voxel_info->info_name[log->cur_anim_type], hash1, log->voxel_info->base_path, hash2);
106
107 int32 f = log->anim_pc;
108 if ((f < 0) || (f >= (int32)pAnim->frame_qty)) {
109 f = (pAnim->frame_qty - 1);
110 }
111 PXmarker_PSX &marker = PXFrameEnOfAnim(f, pAnim)->markers[ORG_POS];
112 float dx, dy, dz;
113 marker.GetXYZ(&dx, &dy, &dz);
114
115 // Make the actors orientation matrix
116 int32 pan;
117 if (log->auto_panning == FALSE8)
118 pan = (int32)((log->pan - log->pan_adjust) * 4096);
119 else
120 pan = (int32)((log->auto_display_pan - log->pan_adjust) * 4096);
121
122 act.rot.vx = 0;
123 act.rot.vy = (int16)pan;
124 act.rot.vz = 0;
125
126 // Because only one level in the hierarchy this is the lw matrix
127 RotMatrix_gte(&act.rot, &act.lw);
128 act.lw.t[0] = (int32)log->mega->actor_xyz.x;
129 act.lw.t[1] = (int32)log->mega->actor_xyz.y;
130 act.lw.t[2] = (int32)log->mega->actor_xyz.z;
131
132 // the bone local frame has the hip at 0,0,0
133 // so put the hip at correct world height
134 // uint32 dy = ( marker.pos.y == 0 ) ? 100 : marker.pos.y;
135 // if ( log->cur_anim_type == __BEING_SHOT_DEAD ) dy = 0;
136 act.lw.t[1] += (int32)dy;
137
138 // Set the actors true rotation & position values
139 act.truePos.x = (int32)log->mega->actor_xyz.x;
140 act.truePos.y = (int32)log->mega->actor_xyz.y;
141 act.truePos.z = (int32)log->mega->actor_xyz.z;
142
143 act.truePos.y += (int32)dy;
144
145 act.trueRot.vx = 0;
146
147 if (log->auto_panning == FALSE8)
148 act.trueRot.vy = (int16)(log->pan * 4096);
149 else
150 act.trueRot.vy = (int16)(log->auto_display_pan * 4096);
151 act.trueRot.vz = 0;
152
153 //
154 thisActor.log = log;
155
156 // if selected then set ambient to be ambientSelect otherwise it's ambient normal...
157 uint8 r = 0;
158 uint8 g = 0;
159 uint8 b = 0;
160
161 if (id == sel_id) {
162 GetSelectedMegaRGB(r, g, b);
163 }
164
165 // mega RGB is 0-256
166 thisActor.r = r;
167 thisActor.g = g;
168 thisActor.b = b;
169
170 // must be reset
171 log->pan_adjust = FLOAT_ZERO;
172
173 // And on to the next actor
174 actorsToDraw++;
175 g_mission->nActorsDrawn++;
176 }
177 }
178 }
179
180 StageDrawPoly(actors, actorsToDraw);
181 }
182
183 } // End of namespace ICB
184