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