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 */
22
23 #include "ags/shared/ac/game_setup_struct.h"
24 #include "ags/engine/ac/view_frame.h"
25 #include "ags/engine/debugging/debug_log.h"
26 #include "ags/shared/ac/sprite_cache.h"
27 #include "ags/shared/gfx/bitmap.h"
28 #include "ags/engine/script/runtime_script_value.h"
29 #include "ags/engine/ac/dynobj/cc_audio_clip.h"
30 #include "ags/engine/ac/draw.h"
31 #include "ags/shared/ac/game_version.h"
32 #include "ags/engine/media/audio/audio_system.h"
33 #include "ags/shared/debugging/out.h"
34 #include "ags/engine/script/script_api.h"
35 #include "ags/engine/script/script_runtime.h"
36 #include "ags/globals.h"
37
38 namespace AGS3 {
39
40 using AGS::Shared::Bitmap;
41 using AGS::Shared::Graphics;
42
43
44
45
46
47
48
ViewFrame_GetFlipped(ScriptViewFrame * svf)49 int ViewFrame_GetFlipped(ScriptViewFrame *svf) {
50 if (_G(views)[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE)
51 return 1;
52 return 0;
53 }
54
ViewFrame_GetGraphic(ScriptViewFrame * svf)55 int ViewFrame_GetGraphic(ScriptViewFrame *svf) {
56 return _G(views)[svf->view].loops[svf->loop].frames[svf->frame].pic;
57 }
58
ViewFrame_SetGraphic(ScriptViewFrame * svf,int newPic)59 void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic) {
60 _G(views)[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic;
61 }
62
ViewFrame_GetLinkedAudio(ScriptViewFrame * svf)63 ScriptAudioClip *ViewFrame_GetLinkedAudio(ScriptViewFrame *svf) {
64 int soundIndex = _G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound;
65 if (soundIndex < 0)
66 return nullptr;
67
68 return &_GP(game).audioClips[soundIndex];
69 }
70
ViewFrame_SetLinkedAudio(ScriptViewFrame * svf,ScriptAudioClip * clip)71 void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip *clip) {
72 int newSoundIndex = -1;
73 if (clip != nullptr)
74 newSoundIndex = clip->id;
75
76 _G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex;
77 }
78
ViewFrame_GetSound(ScriptViewFrame * svf)79 int ViewFrame_GetSound(ScriptViewFrame *svf) {
80 // convert audio clip to old-style sound number
81 return get_old_style_number_for_sound(_G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound);
82 }
83
ViewFrame_SetSound(ScriptViewFrame * svf,int newSound)84 void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound) {
85 if (newSound < 1) {
86 _G(views)[svf->view].loops[svf->loop].frames[svf->frame].audioclip = -1;
87 } else {
88 // convert sound number to audio clip
89 ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, newSound);
90 if (clip == nullptr)
91 quitprintf("!SetFrameSound: audio clip aSound%d not found", newSound);
92
93 _G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound =
94 _GP(game).IsLegacyAudioSystem() ? newSound : clip->id;
95 _G(views)[svf->view].loops[svf->loop].frames[svf->frame].audioclip = clip->id;
96 }
97 }
98
ViewFrame_GetSpeed(ScriptViewFrame * svf)99 int ViewFrame_GetSpeed(ScriptViewFrame *svf) {
100 return _G(views)[svf->view].loops[svf->loop].frames[svf->frame].speed;
101 }
102
ViewFrame_GetView(ScriptViewFrame * svf)103 int ViewFrame_GetView(ScriptViewFrame *svf) {
104 return svf->view + 1;
105 }
106
ViewFrame_GetLoop(ScriptViewFrame * svf)107 int ViewFrame_GetLoop(ScriptViewFrame *svf) {
108 return svf->loop;
109 }
110
ViewFrame_GetFrame(ScriptViewFrame * svf)111 int ViewFrame_GetFrame(ScriptViewFrame *svf) {
112 return svf->frame;
113 }
114
115 //=============================================================================
116
precache_view(int view)117 void precache_view(int view) {
118 if (view < 0)
119 return;
120
121 for (int i = 0; i < _G(views)[view].numLoops; i++) {
122 for (int j = 0; j < _G(views)[view].loops[i].numFrames; j++)
123 _GP(spriteset).Precache(_G(views)[view].loops[i].frames[j].pic);
124 }
125 }
126
127 // the specified frame has just appeared, see if we need
128 // to play a sound or whatever
CheckViewFrame(int view,int loop,int frame,int sound_volume)129 void CheckViewFrame(int view, int loop, int frame, int sound_volume) {
130 ScriptAudioChannel *channel = nullptr;
131 if (_GP(game).IsLegacyAudioSystem()) {
132 // sound field contains legacy sound num, so we also need an actual clip index
133 const int sound = _G(views)[view].loops[loop].frames[frame].sound;
134 int &clip_id = _G(views)[view].loops[loop].frames[frame].audioclip;
135 if (sound > 0) {
136 if (clip_id < 0) {
137 ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, sound);
138 if (!clip)
139 return;
140 clip_id = clip->id;
141 }
142 channel = play_audio_clip_by_index(clip_id);
143 }
144 } else {
145 if (_G(views)[view].loops[loop].frames[frame].sound >= 0) {
146 // play this sound (eg. footstep)
147 channel = play_audio_clip_by_index(_G(views)[view].loops[loop].frames[frame].sound);
148 }
149 }
150 if (sound_volume != SCR_NO_VALUE && channel != nullptr) {
151 AudioChannelsLock lock;
152 auto *ch = lock.GetChannel(channel->id);
153 if (ch)
154 ch->set_volume_percent(ch->get_volume() * sound_volume / 100);
155 }
156 }
157
158 // draws a view frame, flipped if appropriate
DrawViewFrame(Bitmap * ds,const ViewFrame * vframe,int x,int y,bool alpha_blend)159 void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend) {
160 // NOTE: DrawViewFrame supports alpha blending only since OPT_SPRITEALPHA;
161 // this is why there's no sense in blending if it's not set (will do no good anyway).
162 if (alpha_blend && _GP(game).options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) {
163 Bitmap *vf_bmp = _GP(spriteset)[vframe->pic];
164 Bitmap *src = vf_bmp;
165 if (vframe->flags & VFLG_FLIPSPRITE) {
166 src = new Bitmap(vf_bmp->GetWidth(), vf_bmp->GetHeight(), vf_bmp->GetColorDepth());
167 src->FlipBlt(vf_bmp, 0, 0, Shared::kBitmap_HFlip);
168 }
169 draw_sprite_support_alpha(ds, true, x, y, src, (_GP(game).SpriteInfos[vframe->pic].Flags & SPF_ALPHACHANNEL) != 0);
170 if (src != vf_bmp)
171 delete src;
172 } else {
173 if (vframe->flags & VFLG_FLIPSPRITE)
174 ds->FlipBlt(_GP(spriteset)[vframe->pic], x, y, Shared::kBitmap_HFlip);
175 else
176 ds->Blit(_GP(spriteset)[vframe->pic], x, y, Shared::kBitmap_Transparency);
177 }
178 }
179
180 //=============================================================================
181 //
182 // Script API Functions
183 //
184 //=============================================================================
185
186 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetFlipped(void * self,const RuntimeScriptValue * params,int32_t param_count)187 RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) {
188 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFlipped);
189 }
190
191 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)192 RuntimeScriptValue Sc_ViewFrame_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) {
193 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFrame);
194 }
195 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetGraphic(void * self,const RuntimeScriptValue * params,int32_t param_count)196 RuntimeScriptValue Sc_ViewFrame_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) {
197 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetGraphic);
198 }
199
200 // void (ScriptViewFrame *svf, int newPic)
Sc_ViewFrame_SetGraphic(void * self,const RuntimeScriptValue * params,int32_t param_count)201 RuntimeScriptValue Sc_ViewFrame_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) {
202 API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetGraphic);
203 }
204
205 // ScriptAudioClip* (ScriptViewFrame *svf)
Sc_ViewFrame_GetLinkedAudio(void * self,const RuntimeScriptValue * params,int32_t param_count)206 RuntimeScriptValue Sc_ViewFrame_GetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) {
207 API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, _GP(ccDynamicAudioClip), ViewFrame_GetLinkedAudio);
208 }
209
210 // void (ScriptViewFrame *svf, ScriptAudioClip* clip)
Sc_ViewFrame_SetLinkedAudio(void * self,const RuntimeScriptValue * params,int32_t param_count)211 RuntimeScriptValue Sc_ViewFrame_SetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) {
212 API_OBJCALL_VOID_POBJ(ScriptViewFrame, ViewFrame_SetLinkedAudio, ScriptAudioClip);
213 }
214
215 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetLoop(void * self,const RuntimeScriptValue * params,int32_t param_count)216 RuntimeScriptValue Sc_ViewFrame_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) {
217 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetLoop);
218 }
219
220 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetSound(void * self,const RuntimeScriptValue * params,int32_t param_count)221 RuntimeScriptValue Sc_ViewFrame_GetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) {
222 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSound);
223 }
224
225 // void (ScriptViewFrame *svf, int newSound)
Sc_ViewFrame_SetSound(void * self,const RuntimeScriptValue * params,int32_t param_count)226 RuntimeScriptValue Sc_ViewFrame_SetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) {
227 API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetSound);
228 }
229
230 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)231 RuntimeScriptValue Sc_ViewFrame_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) {
232 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSpeed);
233 }
234
235 // int (ScriptViewFrame *svf)
Sc_ViewFrame_GetView(void * self,const RuntimeScriptValue * params,int32_t param_count)236 RuntimeScriptValue Sc_ViewFrame_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) {
237 API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetView);
238 }
239
240
RegisterViewFrameAPI()241 void RegisterViewFrameAPI() {
242 ccAddExternalObjectFunction("ViewFrame::get_Flipped", Sc_ViewFrame_GetFlipped);
243 ccAddExternalObjectFunction("ViewFrame::get_Frame", Sc_ViewFrame_GetFrame);
244 ccAddExternalObjectFunction("ViewFrame::get_Graphic", Sc_ViewFrame_GetGraphic);
245 ccAddExternalObjectFunction("ViewFrame::set_Graphic", Sc_ViewFrame_SetGraphic);
246 ccAddExternalObjectFunction("ViewFrame::get_LinkedAudio", Sc_ViewFrame_GetLinkedAudio);
247 ccAddExternalObjectFunction("ViewFrame::set_LinkedAudio", Sc_ViewFrame_SetLinkedAudio);
248 ccAddExternalObjectFunction("ViewFrame::get_Loop", Sc_ViewFrame_GetLoop);
249 ccAddExternalObjectFunction("ViewFrame::get_Sound", Sc_ViewFrame_GetSound);
250 ccAddExternalObjectFunction("ViewFrame::set_Sound", Sc_ViewFrame_SetSound);
251 ccAddExternalObjectFunction("ViewFrame::get_Speed", Sc_ViewFrame_GetSpeed);
252 ccAddExternalObjectFunction("ViewFrame::get_View", Sc_ViewFrame_GetView);
253 }
254
255 } // namespace AGS3
256