00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "SKFPlayer.h"
00021
00022 #include "u8/ConvertShapeU8.h"
00023 #include "RawArchive.h"
00024 #include "Shape.h"
00025 #include "Texture.h"
00026 #include "SoftRenderSurface.h"
00027 #include "PaletteManager.h"
00028 #include "MusicProcess.h"
00029 #include "AudioProcess.h"
00030 #include "IDataSource.h"
00031 #include "AudioMixer.h"
00032 #include "RawAudioSample.h"
00033 #include "Font.h"
00034 #include "FontManager.h"
00035 #include "RenderedText.h"
00036
00037 #include "SDL.h"
00038
00039
00040 enum SKFAction {
00041 SKF_PlayMusic = 3,
00042 SKF_SlowStopMusic = 4,
00043 SKF_PlaySFX = 5,
00044 SKF_StopSFX = 6,
00045 SKF_SetSpeed = 7,
00046 SKF_FadeOut = 8,
00047 SKF_FadeIn = 9,
00048 SKF_Wait = 12,
00049 SKF_PlaySound = 14,
00050 SKF_FadeWhite = 15,
00051 SKF_ClearSubs = 18
00052 };
00053
00054 struct SKFEvent {
00055 unsigned int frame;
00056 SKFAction action;
00057 unsigned int data;
00058 };
00059
00060
00061 static const int FADESTEPS = 16;
00062
00063
00064 SKFPlayer::SKFPlayer(RawArchive* movie, int width_, int height_, bool introMusicHack_)
00065 : width(width_), height(height_), skf(movie),
00066 curframe(0), curobject(0), curaction(0), curevent(0), playing(false),
00067 timer(0), framerate(15), fadecolour(0), fadelevel(0), buffer(0), subs(0),
00068 introMusicHack(introMusicHack_)
00069 {
00070 IDataSource* eventlist = skf->get_datasource(0);
00071 if (!eventlist)
00072 {
00073 perr << "No eventlist found in SKF" << std::endl;
00074 return;
00075 }
00076
00077 parseEventList(eventlist);
00078 delete eventlist;
00079
00080 buffer = RenderSurface::CreateSecondaryRenderSurface(width, height);
00081 }
00082
00083 SKFPlayer::~SKFPlayer()
00084 {
00085 for (unsigned int i = 0; i < events.size(); ++i)
00086 delete events[i];
00087
00088 delete skf;
00089 delete buffer;
00090 delete subs;
00091 }
00092
00093 void SKFPlayer::parseEventList(IDataSource* eventlist)
00094 {
00095 uint16 frame = eventlist->read2();
00096 while (frame != 0xFFFF) {
00097 SKFEvent* ev = new SKFEvent;
00098 ev->frame = frame;
00099 ev->action = static_cast<SKFAction>(eventlist->read2());
00100 ev->data = eventlist->read2();
00101 events.push_back(ev);
00102
00103 frame = eventlist->read2();
00104 }
00105 }
00106
00107 void SKFPlayer::start()
00108 {
00109 buffer->BeginPainting();
00110 buffer->Fill32(0, 0, 0, width, height);
00111 buffer->EndPainting();
00112 MusicProcess* musicproc = MusicProcess::get_instance();
00113 if (musicproc) musicproc->playMusic(0);
00114 playing = true;
00115 lastupdate = SDL_GetTicks();
00116 }
00117
00118 void SKFPlayer::stop()
00119 {
00120 MusicProcess* musicproc = MusicProcess::get_instance();
00121 if (musicproc && !introMusicHack) musicproc->playMusic(0);
00122 playing = false;
00123 }
00124
00125 void SKFPlayer::paint(RenderSurface* surf, int )
00126 {
00127 if (!buffer) return;
00128
00129 Texture* tex = buffer->GetSurfaceAsTexture();
00130
00131 if (!fadelevel) {
00132 surf->Blit(tex, 0, 0, width, height, 0, 0);
00133 if (subs)
00134 subs->draw(surf, 60, subtitley);
00135 } else {
00136 uint32 fade = TEX32_PACK_RGBA(fadecolour,fadecolour,fadecolour,
00137 (fadelevel*255)/FADESTEPS);
00138 surf->FadedBlit(tex, 0, 0, width, height, 0, 0, fade);
00139 if (subs)
00140 subs->drawBlended(surf, 60, subtitley, fade);
00141 }
00142 }
00143
00144 void SKFPlayer::run()
00145 {
00146 if (!playing || !buffer) return;
00147
00148
00149 if (curaction) {
00150 if (curaction == SKF_FadeOut || curaction == SKF_FadeWhite) {
00151 fadelevel++;
00152 if (fadelevel == FADESTEPS) curaction = 0;
00153 } else if (curaction == SKF_FadeIn) {
00154 fadelevel--;
00155 if (fadelevel == 0) curaction = 0;
00156 } else {
00157 pout << "Unknown fade action: " << curaction << std::endl;
00158 }
00159 }
00160
00161
00162 uint32 now = SDL_GetTicks();
00163 if (lastupdate + (1000/framerate) > now) return;
00164
00165 lastupdate += (1000/framerate);
00166
00167
00168 if (timer) {
00169 timer--;
00170 return;
00171 }
00172
00173 Pentagram::Font* redfont;
00174 redfont = FontManager::get_instance()->getGameFont(6, true);
00175
00176 MusicProcess* musicproc = MusicProcess::get_instance();
00177 AudioProcess* audioproc = AudioProcess::get_instance();
00178
00179
00180 while (curevent < events.size() && events[curevent]->frame <= curframe) {
00181
00182 switch (events[curevent]->action)
00183 {
00184 case SKF_FadeOut:
00185 curaction = SKF_FadeOut;
00186 fadecolour = 0;
00187 fadelevel = 0;
00188
00189 break;
00190 case SKF_FadeIn:
00191 curaction = SKF_FadeIn;
00192 fadelevel = FADESTEPS;
00193
00194 break;
00195 case SKF_FadeWhite:
00196 curaction = SKF_FadeWhite;
00197 fadecolour = 0xFF;
00198 fadelevel = 0;
00199
00200 break;
00201 case SKF_Wait:
00202
00203 timer = events[curevent]->data;
00204 curevent++;
00205 return;
00206 case SKF_PlayMusic:
00207
00208 if (musicproc) musicproc->playMusic(events[curevent]->data);
00209 break;
00210 case SKF_SlowStopMusic:
00211 POUT ("SlowStopMusic");
00212 if (musicproc && !introMusicHack) musicproc->playMusic(0);
00213 break;
00214 case SKF_PlaySFX:
00215
00216 if (audioproc) audioproc->playSFX(events[curevent]->data,0x60,0,0);
00217 break;
00218 case SKF_StopSFX:
00219
00220 if (audioproc) audioproc->stopSFX(events[curevent]->data,0);
00221 break;
00222 case SKF_SetSpeed:
00223 POUT("SetSpeed " << events[curevent]->data);
00224
00225 break;
00226 case SKF_PlaySound:
00227 {
00228
00229
00230 if (audioproc) {
00231 uint8* buffer = skf->get_object(events[curevent]->data);
00232 uint32 bufsize = skf->get_size(events[curevent]->data);
00233 Pentagram::AudioSample* s;
00234 uint32 rate = buffer[6] + (buffer[7]<<8);
00235 bool stereo = (buffer[8] == 2);
00236 s = new Pentagram::RawAudioSample(buffer+34, bufsize-34,
00237 rate, true, stereo);
00238 audioproc->playSample(s, 0x60, 0);
00239
00240 }
00241
00242
00243 char* textbuf = reinterpret_cast<char*>(
00244 skf->get_object(events[curevent]->data-1));
00245 uint32 textsize = skf->get_size(events[curevent]->data-1);
00246 if (textsize > 7) {
00247 std::string subtitle = (textbuf+6);
00248 delete subs;
00249 subtitley = textbuf[4] + (textbuf[5]<<8);
00250 unsigned int remaining;
00251 subs = redfont->renderText(subtitle, remaining, 200, 0,
00252 Pentagram::Font::TEXT_CENTER);
00253 }
00254 delete textbuf;
00255
00256
00257 break;
00258 }
00259 case SKF_ClearSubs:
00260
00261 delete subs;
00262 subs = 0;
00263 break;
00264 default:
00265 pout << "Unknown action" << std::endl;
00266 break;
00267 }
00268
00269 curevent++;
00270 }
00271
00272 curframe++;
00273
00274 PaletteManager* palman = PaletteManager::get_instance();
00275 IDataSource* object;
00276
00277 uint16 objecttype = 0;
00278 do {
00279 curobject++;
00280 if (curobject >= skf->getCount()) {
00281 stop();
00282 return;
00283 }
00284
00285
00286 object = skf->get_datasource(curobject);
00287 if (!object || object->getSize() < 2)
00288 continue;
00289
00290 objecttype = object->read2();
00291
00292
00293
00294
00295
00296 if (objecttype == 1) {
00297 palman->load(PaletteManager::Pal_Movie, *object);
00298 }
00299
00300 if (objecttype != 2)
00301 delete object;
00302
00303 } while (objecttype != 2);
00304
00305 if (objecttype == 2) {
00306 object->seek(0);
00307 Shape* shape = new Shape(object, &U8SKFShapeFormat);
00308 Pentagram::Palette* pal= palman->getPalette(PaletteManager::Pal_Movie);
00309 shape->setPalette(pal);
00310 buffer->BeginPainting();
00311 buffer->Paint(shape, 0, 0, 0);
00312 buffer->EndPainting();
00313 delete shape;
00314
00315 delete object;
00316 }
00317
00318 timer = 1;
00319 }
00320