aboutsummaryrefslogtreecommitdiff
path: root/scumm/actor.h
blob: 2ebfaf02c75bc9ab68f688269f04491b1b5558a2 (plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001/2002 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header$
 *
 */


#ifndef ACTOR_H
#define ACTOR_H

#include <string.h>
#include "scummsys.h"

class Scumm;

enum MoveFlags {
	MF_NEW_LEG = 1,
	MF_IN_LEG = 2,
	MF_TURN = 4,
	MF_LAST_LEG = 8
};

struct ActorWalkData {
	int16 destx, desty;						// Final destination
	byte destbox;
	int16 destdir;
	byte curbox;
	int16 x, y;										// Current position
	int16 newx, newy;							// Next position on our way to the destination
	int32 XYFactor, YXFactor;
	uint16 xfrac, yfrac;
	int point3x, point3y;
};

struct CostumeData {
	byte active[16];
	uint16 animCounter1;
	byte animCounter2;
	uint16 stopped;
	uint16 curpos[16];
	uint16 start[16];
	uint16 end[16];
	uint16 frame[16];

	void reset() {
		stopped = 0;
		for (int i = 0; i < 16; i++) {
			active[i] = 0;
			curpos[i] = start[i] = end[i] = frame[i] = 0xFFFF;
		}
	}
};

class Actor {

public:
	int x, y, top, bottom;
	int elevation;
	uint width;
	byte number;
	uint16 facing;
	uint16 costume;
	byte room;
	byte talkColor;
	byte scalex, scaley;
	byte charset;
	int16 newDirection;
	byte moving;
	byte ignoreBoxes;
	byte forceClip;
	byte initFrame, walkFrame, standFrame, talkFrame1, talkFrame2;
	bool needRedraw, needBgReset, costumeNeedsInit, visible;
	byte shadow_mode;
	bool flip;
	uint speedx, speedy;
	
	// FIXME: the "frame" field is never set, so it is always stays at 0. I am not sure
	// if at some point in the past it was actually set (somebody wanna check?). There are
	// two possibilities: either we just scratch this and hope all works fine, or we come
	// up with a "correct" implementation.
	// The actor.cpp code uses this to determine if the actor shows a walk animation.
	// The script_v2.cpp code uses it for o6_kernelFunction:212.
	// The save/load code (re)stores it.
	// And debug.cpp prints it for debugging purposes.
	byte frame;

	byte walkbox;
	byte animProgress, animSpeed;
	int16 new_1, new_2;
	uint16 talk_script, walk_script;
	byte new_3;
	int8 layer;
	ActorWalkData walkdata;
	int16 animVariable[16];
	uint16 sound[8];
	CostumeData cost;
	byte palette[256];

protected:
	Scumm *_vm;

public:

	// Constructor, sets all data to 0
	  Actor() {
		memset(this, 0, sizeof(Actor));
	} void initActorClass(Scumm *scumm) {
		_vm = scumm;
	}
//protected:
	void hideActor();
	void showActor();

	void initActor(int mode);
	void putActor(int x, int y, byte room);
	void setActorWalkSpeed(uint newSpeedX, uint newSpeedY);
protected:
	int calcMovementFactor(int newx, int newy);
	int actorWalkStep();
	int remapDirection(int dir, bool is_walking);
	void setupActorScale();
public:
	void stopActorMoving();
	void startWalkAnim(int cmd, int angle);
	void startAnimActor(int frame);

protected:
	void setBox(int box);
	int updateActorDirection(bool is_walking);

public:
	void setDirection(int direction);
	int getActorXYPos(int &x, int &y);

	AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY, int pathfrom);
protected:
	void adjustActorPos();
public:
	void turnToDirection(int newdir);
	void walkActor();
	void drawActorCostume();
	void animateCostume();
	void setActorCostume(int c);
	byte *getActorName();
	void startWalkActor(int x, int y, int dir);

	void remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold);
	void walkActorOld();

	void animateActor(int anim);

	bool isInCurrentRoom() {
		return room == _vm->_currentRoom;
	}
	int getRoom() {
		return room;
	}

	int getAnimVar(byte var) {
		return animVariable[var];
	}
	void setAnimVar(byte var, int value) {
		animVariable[var] = value;
	}
	
	void classChanged(int cls, bool value);

protected:
	bool isInClass(int cls);
};

#endif