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 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 * Functions to set up moving actors' reels.
22 */
23
24 #include "tinsel/handle.h"
25 #include "tinsel/pcode.h" // For D_UP, D_DOWN
26 #include "tinsel/rince.h"
27
28 #include "common/textconsole.h"
29 #include "common/util.h"
30
31 namespace Tinsel {
32
33 //----------------- LOCAL GLOBAL DATA --------------------
34
35 enum {
36 NUM_INTERVALS = REQ_MAIN_SCALES - 1,
37
38 // 2 for up and down, 3 allow enough entries for 3 fully subscribed moving actors' worth
39 MAX_SCRENTRIES = NUM_INTERVALS*2*3
40 };
41
42 struct SCIdataStruct {
43 int actor;
44 int scale;
45 int direction;
46 SCNHANDLE reels[4];
47 };
48
49 // FIXME: Avoid non-const global vars
50
51 static SCIdataStruct g_SCIdata[MAX_SCRENTRIES];
52
53 static int g_scrEntries = 0;
54
55 /**
56 * Sets an actor's walk reels
57 */
58
SetWalkReels(PMOVER pMover,int scale,SCNHANDLE al,SCNHANDLE ar,SCNHANDLE af,SCNHANDLE aa)59 void SetWalkReels(PMOVER pMover, int scale,
60 SCNHANDLE al, SCNHANDLE ar, SCNHANDLE af, SCNHANDLE aa) {
61 assert(scale > 0 && scale <= TOTAL_SCALES);
62
63 pMover->walkReels[scale-1][LEFTREEL] = al;
64 pMover->walkReels[scale-1][RIGHTREEL] = ar;
65 pMover->walkReels[scale-1][FORWARD] = af;
66 pMover->walkReels[scale-1][AWAY] = aa;
67 }
68
69
70 /**
71 * Sets an actor's stand reels
72 */
73
SetStandReels(PMOVER pMover,int scale,SCNHANDLE al,SCNHANDLE ar,SCNHANDLE af,SCNHANDLE aa)74 void SetStandReels(PMOVER pMover, int scale,
75 SCNHANDLE al, SCNHANDLE ar, SCNHANDLE af, SCNHANDLE aa) {
76 assert(scale > 0 && scale <= TOTAL_SCALES);
77
78 pMover->standReels[scale-1][LEFTREEL] = al;
79 pMover->standReels[scale-1][RIGHTREEL] = ar;
80 pMover->standReels[scale-1][FORWARD] = af;
81 pMover->standReels[scale-1][AWAY] = aa;
82 }
83
84
85 /**
86 * Sets an actor's talk reels
87 */
88
SetTalkReels(PMOVER pMover,int scale,SCNHANDLE al,SCNHANDLE ar,SCNHANDLE af,SCNHANDLE aa)89 void SetTalkReels(PMOVER pMover, int scale,
90 SCNHANDLE al, SCNHANDLE ar, SCNHANDLE af, SCNHANDLE aa) {
91 assert(scale > 0 && scale <= TOTAL_SCALES);
92
93 pMover->talkReels[scale-1][LEFTREEL] = al;
94 pMover->talkReels[scale-1][RIGHTREEL] = ar;
95 pMover->talkReels[scale-1][FORWARD] = af;
96 pMover->talkReels[scale-1][AWAY] = aa;
97 }
98
99 /**
100 * Return handle to actor's talk reel at present scale and direction.
101 */
GetMoverTalkReel(PMOVER pActor,TFTYPE dirn)102 SCNHANDLE GetMoverTalkReel(PMOVER pActor, TFTYPE dirn) {
103 assert(1 <= pActor->scale && pActor->scale <= TOTAL_SCALES);
104 switch (dirn) {
105 case TF_NONE:
106 return pActor->talkReels[pActor->scale-1][pActor->direction];
107
108 case TF_UP:
109 return pActor->talkReels[pActor->scale-1][AWAY];
110
111 case TF_DOWN:
112 return pActor->talkReels[pActor->scale-1][FORWARD];
113
114 case TF_LEFT:
115 return pActor->talkReels[pActor->scale-1][LEFTREEL];
116
117 case TF_RIGHT:
118 return pActor->talkReels[pActor->scale-1][RIGHTREEL];
119
120 default:
121 error("GetMoverTalkReel() - illegal direction");
122 }
123 }
124
125 /**
126 * scalingreels
127 */
SetScalingReels(int actor,int scale,int direction,SCNHANDLE left,SCNHANDLE right,SCNHANDLE forward,SCNHANDLE away)128 void SetScalingReels(int actor, int scale, int direction,
129 SCNHANDLE left, SCNHANDLE right, SCNHANDLE forward, SCNHANDLE away) {
130 assert(scale >= 1 && scale <= NUM_MAINSCALES); // invalid scale
131 assert(!(scale == 1 && direction == D_UP) &&
132 !(scale == NUM_MAINSCALES && direction == D_DOWN)); // illegal direction from scale
133
134 assert(g_scrEntries < MAX_SCRENTRIES); // Scaling reels limit reached!
135
136 g_SCIdata[g_scrEntries].actor = actor;
137 g_SCIdata[g_scrEntries].scale = scale;
138 g_SCIdata[g_scrEntries].direction = direction;
139 g_SCIdata[g_scrEntries].reels[LEFTREEL] = left;
140 g_SCIdata[g_scrEntries].reels[RIGHTREEL] = right;
141 g_SCIdata[g_scrEntries].reels[FORWARD] = forward;
142 g_SCIdata[g_scrEntries].reels[AWAY] = away;
143 g_scrEntries++;
144 }
145
146 /**
147 * ScalingReel
148 */
ScalingReel(int ano,int scale1,int scale2,DIRECTION reel)149 SCNHANDLE ScalingReel(int ano, int scale1, int scale2, DIRECTION reel) {
150 int d; // Direction
151
152 // The smaller the number, the bigger the scale
153 if (scale1 < scale2)
154 d = D_DOWN;
155 else
156 d = D_UP;
157
158 for (int i = 0; i < g_scrEntries; i++) {
159 if (g_SCIdata[i].actor == ano && g_SCIdata[i].scale == scale1 && g_SCIdata[i].direction == d) {
160 if (g_SCIdata[i].reels[reel] == TF_NONE)
161 return 0;
162 else
163 return g_SCIdata[i].reels[reel];
164 }
165 }
166 return 0;
167 }
168
169 /**
170 * RebootScalingReels
171 */
RebootScalingReels()172 void RebootScalingReels() {
173 g_scrEntries = 0;
174 memset(g_SCIdata, 0, sizeof(g_SCIdata));
175 }
176
177 /**
178 * Discourage them from being ditched.
179 */
TouchMoverReels()180 void TouchMoverReels() {
181 PMOVER pMover;
182 int scale;
183
184 pMover = NextMover(NULL);
185
186 do {
187 for (scale = 0; scale < TOTAL_SCALES; scale++) {
188 TouchMem(pMover->walkReels[scale][LEFTREEL]);
189 }
190 } while ((pMover = NextMover(pMover)) != NULL);
191 }
192
193 } // End of namespace Tinsel
194