From cfe84492adc3ef69154c59d0a94c093bbb9a6609 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Thu, 6 Jan 2005 16:07:46 +0000 Subject: Placard functions are now event-driven, so the blocking palette faders are no longer needed. svn-id: r16450 --- saga/events.cpp | 65 +++++++++++++++++----- saga/events.h | 24 +++++--- saga/gfx.cpp | 28 ---------- saga/gfx.h | 2 - saga/interface.h | 2 +- saga/scene.cpp | 4 +- saga/script.h | 3 +- saga/sfuncs.cpp | 165 +++++++++++++++++++++++++++++++++++++++++++++---------- 8 files changed, 208 insertions(+), 85 deletions(-) diff --git a/saga/events.cpp b/saga/events.cpp index f0f2e63e92..3babfcbc8c 100644 --- a/saga/events.cpp +++ b/saga/events.cpp @@ -259,6 +259,7 @@ int Events::handleImmediate(EVENT *event) { int Events::handleOneShot(EVENT *event) { SURFACE *back_buf; SCRIPT_THREAD *sthread; + Rect rect; static SCENE_BGINFO bginfo; @@ -372,29 +373,48 @@ int Events::handleOneShot(EVENT *event) { case EVENT_ACTIVATE: _vm->_interface->activate(); break; + case EVENT_DEACTIVATE: + _vm->_interface->deactivate(); + break; + case EVENT_SET_STATUS: + _vm->_interface->setStatusText((const char*)event->data); + _vm->_interface->drawStatusBar(_vm->_gfx->getBackBuffer()); + break; + case EVENT_CLEAR_STATUS: + _vm->_interface->setStatusText(""); + _vm->_interface->drawStatusBar(_vm->_gfx->getBackBuffer()); + break; default: break; } break; case SCRIPT_EVENT: - debug(0, "Starting start script #%d", event->param); + switch (event->op) { + case EVENT_EXEC_BLOCKING: + case EVENT_EXEC_NONBLOCKING: + debug(0, "Starting start script #%d", event->param); - sthread = _vm->_script->SThreadCreate(); - if (sthread == NULL) { - _vm->_console->DebugPrintf("Thread creation failed.\n"); - break; - } + sthread = _vm->_script->SThreadCreate(); + if (sthread == NULL) { + _vm->_console->DebugPrintf("Thread creation failed.\n"); + break; + } - sthread->threadVars[kVarAction] = TO_LE_16(event->param2); - sthread->threadVars[kVarObject] = TO_LE_16(event->param3); - sthread->threadVars[kVarWithObject] = TO_LE_16(event->param4); - sthread->threadVars[kVarActor] = TO_LE_16(event->param5); + sthread->threadVars[kVarAction] = TO_LE_16(event->param2); + sthread->threadVars[kVarObject] = TO_LE_16(event->param3); + sthread->threadVars[kVarWithObject] = TO_LE_16(event->param4); + sthread->threadVars[kVarActor] = TO_LE_16(event->param5); - _vm->_script->SThreadExecute(sthread, event->param); + _vm->_script->SThreadExecute(sthread, event->param); - if (event->op == EVENT_BLOCKING) - _vm->_script->SThreadCompleteThread(); + if (event->op == EVENT_EXEC_BLOCKING) + _vm->_script->SThreadCompleteThread(); + break; + case EVENT_THREAD_WAKE: + _vm->_script->wakeUpThreads(event->param); + break; + } break; case CURSOR_EVENT: switch (event->op) { @@ -407,6 +427,25 @@ int Events::handleOneShot(EVENT *event) { default: break; } + break; + case GRAPHICS_EVENT: + switch (event->op) { + case EVENT_FILL_RECT: + rect.top = event->param2; + rect.bottom = event->param3; + rect.left = event->param4; + rect.right = event->param5; + drawRect((SURFACE *)event->data, &rect, event->param); + break; + case EVENT_SETFLAG: + _vm->_render->setFlag(event->param); + break; + case EVENT_CLEARFLAG: + _vm->_render->clearFlag(event->param); + break; + default: + break; + } default: break; } diff --git a/saga/events.h b/saga/events.h index a119d5dd46..876241fc62 100644 --- a/saga/events.h +++ b/saga/events.h @@ -31,10 +31,10 @@ namespace Saga { enum EVENT_TYPES { - ONESHOT_EVENT, - CONTINUOUS_EVENT, - INTERVAL_EVENT, - IMMEDIATE_EVENT + ONESHOT_EVENT, // Event takes no time + CONTINUOUS_EVENT, // Event takes time; next event starts immediately + INTERVAL_EVENT, // Not yet implemented + IMMEDIATE_EVENT // Event takes time; next event starts when event is done }; enum EVENT_FLAGS { @@ -56,7 +56,8 @@ enum EVENT_CODES { INTERFACE_EVENT, ACTOR_EVENT, SCRIPT_EVENT, - CURSOR_EVENT + CURSOR_EVENT, + GRAPHICS_EVENT }; enum EVENT_OPS { @@ -82,15 +83,22 @@ enum EVENT_OPS { EVENT_CYCLESTEP = 2, // INTERFACE events EVENT_ACTIVATE = 1, - EVENT_DEACTIVATE, + EVENT_DEACTIVATE = 2, + EVENT_SET_STATUS = 3, + EVENT_CLEAR_STATUS = 4, // ACTOR events EVENT_MOVE = 1, // SCRIPT events - EVENT_BLOCKING = 1, - EVENT_NONBLOCKING = 2, + EVENT_EXEC_BLOCKING = 1, + EVENT_EXEC_NONBLOCKING = 2, + EVENT_THREAD_WAKE = 3, // CURSOR events EVENT_SHOW = 1, // EVENT_HIDE = 2, // reused + // GRAPHICS events + EVENT_FILL_RECT = 1, + // EVENT_SETFLAG = 4, // reused + // EVENT_CLEARFLAG = 5, // reused // CONTINUOUS events // PALETTE events diff --git a/saga/gfx.cpp b/saga/gfx.cpp index dc3f3bdb5a..b6a5b55652 100644 --- a/saga/gfx.cpp +++ b/saga/gfx.cpp @@ -986,34 +986,6 @@ int Gfx::blackToPal(SURFACE *surface, PALENTRY *src_pal, double percent) { return SUCCESS; } -void Gfx::palToBlackWait(SURFACE *surface, PALENTRY *src_pal, int duration) { - uint32 start_time = _vm->_system->getMillis(); - uint32 cur_time; - - do { - cur_time = _vm->_system->getMillis(); - - palToBlack(surface, src_pal, (double) (cur_time - start_time) / duration); - _vm->processInput(); - _vm->_system->updateScreen(); - _vm->_system->delayMillis(50); - } while (cur_time < start_time + duration); -} - -void Gfx::blackToPalWait(SURFACE *surface, PALENTRY *src_pal, int duration) { - uint32 start_time = _vm->_system->getMillis(); - uint32 cur_time; - - do { - cur_time = _vm->_system->getMillis(); - - blackToPal(surface, src_pal, (double) (cur_time - start_time) / duration); - _vm->processInput(); - _vm->_system->updateScreen(); - _vm->_system->delayMillis(50); - } while (cur_time < start_time + duration); -} - void Gfx::showCursor(bool state) { updateCursor(); g_system->showMouse(state); diff --git a/saga/gfx.h b/saga/gfx.h index e40b8e40ca..61cc760c89 100644 --- a/saga/gfx.h +++ b/saga/gfx.h @@ -107,8 +107,6 @@ public: int getCurrentPal(PALENTRY *src_pal); int palToBlack(SURFACE *surface, PALENTRY *src_pal, double percent); int blackToPal(SURFACE *surface, PALENTRY *src_pal, double percent); - void palToBlackWait(SURFACE *surface, PALENTRY *src_pal, int duration); - void blackToPalWait(SURFACE *surface, PALENTRY *src_pal, int duration); void updateCursor() { setCursor(getWhite()); } void showCursor(bool state); diff --git a/saga/interface.h b/saga/interface.h index 9e2aa382c3..f827191fa8 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -220,6 +220,7 @@ public: int setLeftPortrait(int portrait); int setRightPortrait(int portrait); int draw(); + int drawStatusBar(SURFACE *ds); int update(const Point& imousePt, int update_flag); void addToInventory(int sprite); @@ -229,7 +230,6 @@ public: private: int hitTest(const Point& imousePt, int *ibutton); - int drawStatusBar(SURFACE *ds); int handleCommandUpdate(SURFACE *ds, const Point& imousePt); int handleCommandClick(SURFACE *ds, const Point& imousePt); int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt); diff --git a/saga/scene.cpp b/saga/scene.cpp index 00849c894c..1d8527db09 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -644,7 +644,7 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_ if (_desc.startScriptNum > 0) { event.type = ONESHOT_EVENT; event.code = SCRIPT_EVENT; - event.op = EVENT_BLOCKING; + event.op = EVENT_EXEC_BLOCKING; event.time = 0; event.param = _desc.startScriptNum; event.param2 = 0; // Action @@ -1106,7 +1106,7 @@ int Scene::defaultScene(int param, SCENE_INFO *scene_info) { if (_desc.sceneScriptNum > 0) { event.type = ONESHOT_EVENT; event.code = SCRIPT_EVENT; - event.op = EVENT_NONBLOCKING; + event.op = EVENT_EXEC_NONBLOCKING; event.time = 0; event.param = _desc.sceneScriptNum; event.param2 = 0; // Action diff --git a/saga/script.h b/saga/script.h index 317b43e9a3..f045696fbb 100644 --- a/saga/script.h +++ b/saga/script.h @@ -95,7 +95,8 @@ enum ThreadWaitTypes { kWaitTypeDialogBegin = 4, // waiting for other dialog to finish kWaitTypeWalk = 5, // waiting to finish walking kWaitTypeRequest = 6, // a request is up - kWaitTypePause = 7 + kWaitTypePause = 7, + kWaitTypePlacard = 8 }; enum OpCodes { diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index acb94eac94..5c65c5e6f5 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -29,6 +29,7 @@ #include "saga/actor.h" #include "saga/animation.h" #include "saga/console.h" +#include "saga/events.h" #include "saga/font.h" #include "saga/interface.h" #include "saga/music.h" @@ -932,29 +933,69 @@ int Script::SF_simulSpeech2(SCRIPTFUNC_PARAMS) { return SUCCESS; } +static TEXTLIST_ENTRY *placardTextEntry; + // Script function #48 (0x30) // Param1: string rid int Script::sfPlacard(SCRIPTFUNC_PARAMS) { int stringId; - const char *string; GAME_DISPLAYINFO disp; SURFACE *back_buf = _vm->_gfx->getBackBuffer(); - PALENTRY cur_pal[PAL_ENTRIES]; + static PALENTRY cur_pal[PAL_ENTRIES]; PALENTRY *pal; - - stringId = thread->pop(); - string = getString(stringId); + EVENT event; + EVENT *q_event; + + thread->wait(kWaitTypePlacard); + + _vm->_interface->rememberMode(); + _vm->_interface->setMode(kPanelPlacard); _vm->getDisplayInfo(&disp); - _vm->_gfx->showCursor(false); + stringId = thread->pop(); + + event.type = ONESHOT_EVENT; + event.code = CURSOR_EVENT; + event.op = EVENT_HIDE; + + q_event = _vm->_events->queue(&event); + _vm->_gfx->getCurrentPal(cur_pal); - _vm->_gfx->palToBlackWait(back_buf, cur_pal, kNormalFadeDuration); - _vm->_interface->setStatusText(""); + event.type = IMMEDIATE_EVENT; + event.code = PAL_EVENT; + event.op = EVENT_PALTOBLACK; + event.time = 0; + event.duration = kNormalFadeDuration; + event.data = cur_pal; + + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = INTERFACE_EVENT; + event.op = EVENT_CLEAR_STATUS; + + q_event = _vm->_events->chain(q_event, &event); - Rect rect(disp.logical_w, disp.scene_h); - drawRect(back_buf, &rect, 138); + event.type = ONESHOT_EVENT; + event.code = GRAPHICS_EVENT; + event.op = EVENT_SETFLAG; + event.param = RF_PLACARD; + + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = GRAPHICS_EVENT; + event.op = EVENT_FILL_RECT; + event.data = back_buf; + event.param = 138; + event.param2 = 0; + event.param3 = disp.scene_h; + event.param4 = 0; + event.param5 = disp.logical_w; + + q_event = _vm->_events->chain(q_event, &event); // Put the text in the center of the viewport, assuming it will fit on // one line. If we cannot make that assumption we'll need to extend @@ -962,44 +1003,108 @@ int Script::sfPlacard(SCRIPTFUNC_PARAMS) { // It doesn't end up in exactly the same spot as the original did it, // but it's close enough for now at least. - _vm->textDraw(MEDIUM_FONT_ID, back_buf, string, - disp.logical_w / 2, - (disp.scene_h - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2, - _vm->_gfx->getWhite(), _vm->_gfx->getBlack(), - FONT_OUTLINE | FONT_CENTERED); + TEXTLIST_ENTRY text_entry; + SCENE_INFO scene_info; + + _vm->_scene->getInfo(&scene_info); + + text_entry.color = _vm->_gfx->getWhite(); + text_entry.effect_color = _vm->_gfx->getBlack(); + text_entry.text_x = disp.logical_w / 2; + text_entry.text_y = (disp.scene_h - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2; + text_entry.font_id = MEDIUM_FONT_ID; + text_entry.flags = FONT_OUTLINE | FONT_CENTERED; + text_entry.string = getString(stringId); - _vm->_render->setFlag(RF_PLACARD); - _vm->_render->drawScene(); + placardTextEntry = _vm->textAddEntry(scene_info.text_list, &text_entry); + + event.type = ONESHOT_EVENT; + event.code = TEXT_EVENT; + event.op = EVENT_DISPLAY; + event.data = placardTextEntry; + + q_event = _vm->_events->chain(q_event, &event); _vm->_scene->getBGPal(&pal); - _vm->_gfx->blackToPalWait(back_buf, pal, kNormalFadeDuration); - _vm->_interface->rememberMode(); - _vm->_interface->setMode(kPanelPlacard); + event.type = IMMEDIATE_EVENT; + event.code = PAL_EVENT; + event.op = EVENT_BLACKTOPAL; + event.time = 0; + event.duration = kNormalFadeDuration; + event.data = pal; + + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = SCRIPT_EVENT; + event.op = EVENT_THREAD_WAKE; + event.param = kWaitTypePlacard; + + q_event = _vm->_events->chain(q_event, &event); return SUCCESS; } // Script function #49 (0x31) int Script::sfPlacardOff(SCRIPTFUNC_PARAMS) { - SURFACE *back_buf = _vm->_gfx->getBackBuffer(); - PALENTRY cur_pal[PAL_ENTRIES]; + static PALENTRY cur_pal[PAL_ENTRIES]; PALENTRY *pal; + EVENT event; + EVENT *q_event; + + thread->wait(kWaitTypePlacard); + + _vm->_interface->restoreMode(); - // Fade down _vm->_gfx->getCurrentPal(cur_pal); - _vm->_gfx->palToBlackWait(back_buf, cur_pal, kNormalFadeDuration); - _vm->_render->clearFlag(RF_PLACARD); - _vm->_render->drawScene(); + event.type = IMMEDIATE_EVENT; + event.code = PAL_EVENT; + event.op = EVENT_PALTOBLACK; + event.time = 0; + event.duration = kNormalFadeDuration; + event.data = cur_pal; + + q_event = _vm->_events->queue(&event); + + event.type = ONESHOT_EVENT; + event.code = GRAPHICS_EVENT; + event.op = EVENT_CLEARFLAG; + event.param = RF_PLACARD; + + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = TEXT_EVENT; + event.op = EVENT_REMOVE; + event.data = placardTextEntry; + + q_event = _vm->_events->chain(q_event, &event); - // Fade up _vm->_scene->getBGPal(&pal); - _vm->_gfx->showCursor(true); - _vm->_gfx->blackToPalWait(back_buf, pal, kNormalFadeDuration); + event.type = IMMEDIATE_EVENT; + event.code = PAL_EVENT; + event.op = EVENT_BLACKTOPAL; + event.time = 0; + event.duration = kNormalFadeDuration; + event.data = pal; - _vm->_interface->restoreMode(); + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = CURSOR_EVENT; + event.op = EVENT_SHOW; + + q_event = _vm->_events->chain(q_event, &event); + + event.type = ONESHOT_EVENT; + event.code = SCRIPT_EVENT; + event.op = EVENT_THREAD_WAKE; + event.param = kWaitTypePlacard; + + q_event = _vm->_events->chain(q_event, &event); return SUCCESS; } -- cgit v1.2.3