aboutsummaryrefslogtreecommitdiff
path: root/saga/scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'saga/scene.cpp')
-rw-r--r--saga/scene.cpp1159
1 files changed, 1159 insertions, 0 deletions
diff --git a/saga/scene.cpp b/saga/scene.cpp
new file mode 100644
index 0000000000..3fc9bda076
--- /dev/null
+++ b/saga/scene.cpp
@@ -0,0 +1,1159 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
+ *
+ * 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$
+ *
+ */
+/*
+ Description:
+
+ Scene management module
+
+ Notes:
+*/
+
+#include "reinherit.h"
+
+#include "yslib.h"
+
+/*
+ * Uses the following modules:
+\*--------------------------------------------------------------------------*/
+#include "game_mod.h"
+#include "animation_mod.h"
+#include "console_mod.h"
+#include "cvar_mod.h"
+#include "events_mod.h"
+#include "actionmap_mod.h"
+#include "gfx_mod.h"
+#include "image_mod.h"
+#include "isomap_mod.h"
+#include "script_mod.h"
+#include "objectmap_mod.h"
+#include "palanim_mod.h"
+#include "render_mod.h"
+#include "rscfile_mod.h"
+#include "text_mod.h"
+
+/*
+ * Begin module component
+\*--------------------------------------------------------------------------*/
+#include "scene_mod.h"
+#include "scene.h"
+
+namespace Saga {
+
+static R_SCENE_MODULE SceneModule;
+
+int SCENE_Register(void)
+{
+
+ CVAR_Register_I(&SceneModule.scene_number,
+ "scene", NULL, R_CVAR_READONLY, 0, 0);
+
+ CVAR_RegisterFunc(CF_scenechange,
+ "scene_change", "<Scene number>", R_CVAR_NONE, 1, 1);
+
+ CVAR_RegisterFunc(CF_sceneinfo, "scene_info", NULL, R_CVAR_NONE, 0, 0);
+
+ return R_SUCCESS;
+}
+
+int SCENE_Init(void)
+{
+
+ R_GAME_SCENEDESC gs_desc;
+
+ uchar *scene_lut_p;
+ size_t scene_lut_len;
+
+ const uchar *read_p;
+
+ int result;
+ int i;
+
+ /* Load game-specific scene data
+ * \*------------------------------------------------------------ */
+ GAME_GetSceneInfo(&gs_desc);
+
+ /* Load scene module resource context
+ * \*------------------------------------------------------------ */
+ result = GAME_GetFileContext(&SceneModule.scene_ctxt,
+ R_GAME_RESOURCEFILE, 0);
+ if (result != R_SUCCESS) {
+
+ R_printf(R_STDERR, "Couldn't load scene resource context.\n");
+
+ return R_FAILURE;
+ }
+
+ /* Initialize scene queue
+ * \*------------------------------------------------------------ */
+ SceneModule.scene_queue = ys_dll_create();
+ if (SceneModule.scene_queue == NULL) {
+
+ return R_FAILURE;
+ }
+
+ /* Load scene lookup table
+ * \*------------------------------------------------------------ */
+ R_printf(R_STDOUT,
+ "SCENE_Init(): Loading scene LUT from resource %d.\n",
+ gs_desc.scene_lut_rn);
+
+ result = RSC_LoadResource(SceneModule.scene_ctxt,
+ gs_desc.scene_lut_rn, &scene_lut_p, &scene_lut_len);
+ if (result != R_SUCCESS) {
+
+ R_printf(R_STDERR, "Error: couldn't load scene LUT.\n");
+
+ return R_FAILURE;
+ }
+
+ SceneModule.scene_count = scene_lut_len / 2;
+ SceneModule.scene_max = SceneModule.scene_count - 1;
+
+ SceneModule.scene_lut = (int *)malloc(SceneModule.scene_max *
+ sizeof *SceneModule.scene_lut);
+ if (SceneModule.scene_lut == NULL) {
+ R_printf(R_STDERR,
+ "SCENE_Init(): Memory allocation failed.\n");
+ return R_MEM;
+ }
+
+ read_p = scene_lut_p;
+
+ for (i = 0; i < SceneModule.scene_max; i++) {
+
+ SceneModule.scene_lut[i] = ys_read_u16_le(read_p, &read_p);
+ }
+
+ free(scene_lut_p);
+
+ if (gs_desc.first_scene != 0) {
+ SceneModule.first_scene = gs_desc.first_scene;
+ }
+
+ R_printf(R_STDOUT,
+ "SCENE_Init(): First scene set to %d.\n", SceneModule.first_scene);
+
+ R_printf(R_STDOUT,
+ "SCENE_Init(): LUT has %d entries.\n", SceneModule.scene_max);
+
+ /* Create scene module text list
+ * \*------------------------------------------------------------ */
+ SceneModule.text_list = TEXT_CreateList();
+
+ if (SceneModule.text_list == NULL) {
+ R_printf(R_STDERR,
+ "Error: Couldn't create scene text list.\n");
+
+ return R_FAILURE;
+ }
+
+ SceneModule.init = 1;
+
+ return R_SUCCESS;
+}
+
+int SCENE_Shutdown(void)
+{
+
+ if (SceneModule.init) {
+ SCENE_End();
+ free(SceneModule.scene_lut);
+ }
+
+ return R_SUCCESS;
+}
+
+int SCENE_Queue(R_SCENE_QUEUE * scene_queue)
+{
+ assert(SceneModule.init);
+ assert(scene_queue != NULL);
+
+ ys_dll_add_tail(SceneModule.scene_queue,
+ scene_queue, sizeof *scene_queue);
+
+ return R_SUCCESS;
+}
+
+int SCENE_ClearQueue(void)
+{
+ assert(SceneModule.init);
+
+ ys_dll_delete_all(SceneModule.scene_queue);
+
+ return R_SUCCESS;
+}
+
+int SCENE_Start(void)
+{
+
+ YS_DL_NODE *node;
+ R_SCENE_QUEUE *scene_qdat;
+
+ assert(SceneModule.init);
+
+ if (SceneModule.scene_loaded) {
+ R_printf(R_STDERR,
+ "Error: Can't start game...scene already loaded!\n");
+
+ return R_FAILURE;
+ }
+
+ if (SceneModule.in_game) {
+ R_printf(R_STDERR,
+ "Error: Can't start game...game already started!\n");
+
+ return R_FAILURE;
+ }
+
+ switch (GAME_GetGameType()) {
+
+ case R_GAMETYPE_ITE:
+ ITE_StartProc();
+ break;
+
+ case R_GAMETYPE_IHNM:
+ IHNM_StartProc();
+ break;
+
+ default:
+ R_printf(R_STDERR,
+ "Error: Can't start game... gametype not supported.\n");
+ break;
+ }
+
+ /* Load the head node in scene queue
+ * \*------------------------------------------------------------- */
+ node = ys_dll_head(SceneModule.scene_queue);
+ if (node == NULL) {
+ return R_SUCCESS;
+ }
+
+ scene_qdat = (R_SCENE_QUEUE *)ys_dll_get_data(node);
+ assert(scene_qdat != NULL);
+
+ SCENE_Load(scene_qdat->scene_n,
+ scene_qdat->load_flag,
+ scene_qdat->scene_proc, scene_qdat->scene_desc);
+
+ return R_SUCCESS;
+}
+
+int SCENE_Next(void)
+{
+
+ YS_DL_NODE *node;
+ R_SCENE_QUEUE *scene_qdat;
+
+ assert(SceneModule.init);
+
+ if (!SceneModule.scene_loaded) {
+ R_printf(R_STDERR,
+ "Error: Can't advance scene...no scene loaded!\n");
+
+ return R_FAILURE;
+ }
+
+ if (SceneModule.in_game) {
+ R_printf(R_STDERR,
+ "Error: Can't advance scene...game already started!\n");
+
+ return R_FAILURE;
+ }
+
+ SCENE_End();
+
+ /* Delete the current head node in scene queue
+ * \*------------------------------------------------------------- */
+ node = ys_dll_head(SceneModule.scene_queue);
+ if (node == NULL) {
+ return R_SUCCESS;
+ }
+
+ ys_dll_delete(node);
+
+ /* Load the head node in scene queue
+ * \*------------------------------------------------------------- */
+ node = ys_dll_head(SceneModule.scene_queue);
+ if (node == NULL) {
+ return R_SUCCESS;
+ }
+
+ scene_qdat = (R_SCENE_QUEUE *)ys_dll_get_data(node);
+ assert(scene_qdat != NULL);
+
+ SCENE_Load(scene_qdat->scene_n,
+ scene_qdat->load_flag,
+ scene_qdat->scene_proc, scene_qdat->scene_desc);
+
+ return R_SUCCESS;
+}
+
+int SCENE_Skip(void)
+{
+
+ YS_DL_NODE *node;
+ YS_DL_NODE *prev_node;
+ YS_DL_NODE *skip_node = NULL;
+
+ R_SCENE_QUEUE *scene_qdat = NULL;
+ R_SCENE_QUEUE *skip_qdat = NULL;
+
+ assert(SceneModule.init);
+
+ if (!SceneModule.scene_loaded) {
+
+ R_printf(R_STDERR,
+ "Error: Can't skip scene...no scene loaded.\n");
+
+ return R_FAILURE;
+ }
+
+ if (SceneModule.in_game) {
+
+ R_printf(R_STDERR,
+ "Error: Can't skip scene...game already started.\n");
+
+ return R_FAILURE;
+ }
+
+ /* Walk down scene queue and try to find a skip target
+ * \*------------------------------------------------------------- */
+ node = ys_dll_head(SceneModule.scene_queue);
+ if (node == NULL) {
+
+ R_printf(R_STDERR,
+ "Error: Can't skip scene...no scenes in queue.\n");
+
+ return R_FAILURE;
+ }
+
+ for (node = ys_dll_next(node); node != NULL; node = ys_dll_next(node)) {
+
+ scene_qdat = (R_SCENE_QUEUE *)ys_dll_get_data(node);
+ assert(scene_qdat != NULL);
+
+ if (scene_qdat->scene_skiptarget) {
+
+ skip_node = node;
+ skip_qdat = scene_qdat;
+ break;
+ }
+ }
+
+ /* If skip target found, remove preceding scenes and load
+ * \*------------------------------------------------------------- */
+ if (skip_node != NULL) {
+
+ for (node = ys_dll_prev(skip_node);
+ node != NULL; node = prev_node) {
+
+ prev_node = ys_dll_prev(node);
+
+ ys_dll_delete(node);
+ }
+
+ SCENE_End();
+
+ SCENE_Load(skip_qdat->scene_n,
+ skip_qdat->load_flag,
+ skip_qdat->scene_proc, skip_qdat->scene_desc);
+ }
+
+ /* Search for a scene to skip to */
+
+ return R_SUCCESS;
+}
+
+int SCENE_Change(int scene_num)
+{
+
+ assert(SceneModule.init);
+
+ if (!SceneModule.scene_loaded) {
+ R_printf(R_STDERR,
+ "Error: Can't change scene. No scene currently loaded. "
+ "Game in invalid state.\n");
+
+ return R_FAILURE;
+ }
+
+ if ((scene_num < 0) || (scene_num > SceneModule.scene_max)) {
+
+ R_printf(R_STDERR,
+ "Error: Can't change scene. Invalid scene number.\n");
+
+ return R_FAILURE;
+ }
+
+ if (SceneModule.scene_lut[scene_num] == 0) {
+
+ R_printf(R_STDERR,
+ "Error: Can't change scene; invalid scene descriptor "
+ "resource number (0)\n");
+
+ return R_FAILURE;
+ }
+
+ SCENE_End();
+ SCENE_Load(scene_num, BY_SCENE, DefaultSceneProc, NULL);
+
+ return R_SUCCESS;
+}
+
+int SCENE_GetMode(void)
+{
+ assert(SceneModule.init);
+
+ return SceneModule.scene_mode;
+}
+
+int SCENE_GetZInfo(SCENE_ZINFO * zinfo)
+{
+
+ assert(SceneModule.init);
+
+ zinfo->begin_slope = SceneModule.desc.begin_slope;
+ zinfo->end_slope = SceneModule.desc.end_slope;
+
+ return R_SUCCESS;
+}
+
+int SCENE_GetBGInfo(SCENE_BGINFO * bginfo)
+{
+ R_GAME_DISPLAYINFO di;
+ int x, y;
+
+ assert(SceneModule.init);
+
+ bginfo->bg_buf = SceneModule.bg.buf;
+ bginfo->bg_buflen = SceneModule.bg.buf_len;
+ bginfo->bg_w = SceneModule.bg.w;
+ bginfo->bg_h = SceneModule.bg.h;
+ bginfo->bg_p = SceneModule.bg.p;
+
+ GAME_GetDisplayInfo(&di);
+ x = 0;
+ y = 0;
+
+ if (SceneModule.bg.w < di.logical_w) {
+ x = (di.logical_w - SceneModule.bg.w) / 2;
+ }
+
+ if (SceneModule.bg.h < di.scene_h) {
+ y = (di.scene_h - SceneModule.bg.h) / 2;
+ }
+
+ bginfo->bg_x = x;
+ bginfo->bg_y = y;
+
+ return R_SUCCESS;
+}
+
+int SCENE_GetBGPal(PALENTRY ** pal)
+{
+ assert(SceneModule.init);
+
+ *pal = SceneModule.bg.pal;
+
+ return R_SUCCESS;
+}
+
+int SCENE_GetBGMaskInfo(int *w, int *h, uchar ** buf, size_t * buf_len)
+{
+
+ assert(SceneModule.init);
+
+ if (!SceneModule.bg_mask.loaded) {
+ return R_FAILURE;
+ }
+
+ *w = SceneModule.bg_mask.w;
+ *h = SceneModule.bg_mask.h;
+ *buf = SceneModule.bg_mask.buf;
+ *buf_len = SceneModule.bg_mask.buf_len;
+
+ return R_SUCCESS;
+}
+
+int SCENE_IsBGMaskPresent(void)
+{
+
+ assert(SceneModule.init);
+
+ return SceneModule.bg_mask.loaded;
+}
+
+int SCENE_GetInfo(R_SCENE_INFO * si)
+{
+ assert(SceneModule.init);
+ assert(si != NULL);
+
+ si->text_list = SceneModule.text_list;
+
+ return R_SUCCESS;
+}
+
+int
+SCENE_Load(int scene_num,
+ int load_flag, R_SCENE_PROC scene_proc, R_SCENE_DESC * scene_desc_param)
+{
+
+ R_SCENE_INFO scene_info;
+ ulong res_number = 0;
+ int result;
+ int i;
+
+ assert(SceneModule.init);
+
+ if (SceneModule.scene_loaded == 1) {
+
+ R_printf(R_STDERR, "Error, a scene is already loaded.\n");
+ return R_FAILURE;
+ }
+
+ SceneModule.anim_list = ys_dll_create();
+ SceneModule.scene_mode = 0;
+ SceneModule.load_desc = 1;
+
+ switch (load_flag) {
+
+ case BY_RESOURCE:
+ res_number = scene_num;
+ break;
+
+ case BY_SCENE:
+ assert((scene_num > 0) && (scene_num < SceneModule.scene_max));
+
+ res_number = SceneModule.scene_lut[scene_num];
+ SceneModule.scene_number = scene_num;
+ break;
+
+ case BY_DESC:
+
+ assert(scene_desc_param != NULL);
+ assert(scene_desc_param->res_list != NULL);
+
+ SceneModule.load_desc = 0;
+
+ SceneModule.desc = *scene_desc_param;
+ SceneModule.reslist = scene_desc_param->res_list;
+ SceneModule.reslist_entries = scene_desc_param->res_list_ct;
+ break;
+
+ default:
+ R_printf(R_STDERR, "Error: Invalid scene load flag.\n");
+ return R_FAILURE;
+ break;
+
+ }
+
+ /*
+ * Load scene descriptor and resource list resources
+ \*-------------------------------------------------------------*/
+ if (SceneModule.load_desc) {
+
+ SceneModule.scene_rn = res_number;
+ assert(SceneModule.scene_rn != 0);
+
+ R_printf(R_STDOUT, "Loading scene resource %d:\n", res_number);
+
+ if (LoadSceneDescriptor(res_number) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error reading scene descriptor.\n");
+
+ return R_FAILURE;
+ }
+
+ if (LoadSceneResourceList(SceneModule.desc.res_list_rn)
+ != R_SUCCESS) {
+
+ R_printf(R_STDERR,
+ "Error reading scene resource list.\n");
+
+ return R_FAILURE;
+ }
+ } else {
+
+ R_printf(R_STDOUT, "Loading memory scene resource.\n");
+ }
+
+ /*
+ * Load resources from scene resource list
+ \*-------------------------------------------------------------*/
+ for (i = 0; i < SceneModule.reslist_entries; i++) {
+
+ result = RSC_LoadResource(SceneModule.scene_ctxt,
+ SceneModule.reslist[i].res_number,
+ &SceneModule.reslist[i].res_data,
+ &SceneModule.reslist[i].res_data_len);
+ if (result != R_SUCCESS) {
+
+ R_printf(R_STDERR,
+ "Error: Allocation failure loading scene "
+ "resource list.\n");
+
+ return R_FAILURE;
+ }
+
+ }
+
+ /*
+ * Process resources from scene resource list
+ \*-------------------------------------------------------------*/
+ if (ProcessSceneResources() != R_SUCCESS) {
+
+ R_printf(R_STDERR, "Error loading scene resources.\n");
+
+ return R_FAILURE;
+ }
+
+ /* Load scene script data */
+ if (SceneModule.desc.script_num > 0) {
+
+ if (SCRIPT_Load(SceneModule.desc.script_num) != R_SUCCESS) {
+
+ R_printf(R_STDERR, "Error loading scene script.\n");
+ return R_FAILURE;
+ }
+ }
+
+ SceneModule.scene_loaded = 1;
+
+ if (scene_proc == NULL) {
+ SceneModule.scene_proc = DefaultSceneProc;
+ } else {
+ SceneModule.scene_proc = scene_proc;
+ }
+
+ SCENE_GetInfo(&scene_info);
+
+ SceneModule.scene_proc(SCENE_BEGIN, &scene_info);
+
+ return R_SUCCESS;
+}
+
+int LoadSceneDescriptor(ulong res_number)
+{
+
+ uchar *scene_desc_data;
+ size_t scene_desc_len;
+
+ const uchar *read_p;
+
+ int result;
+
+ result = RSC_LoadResource(SceneModule.scene_ctxt,
+ res_number, &scene_desc_data, &scene_desc_len);
+ if (result != R_SUCCESS) {
+ R_printf(R_STDERR, "Error: couldn't load scene descriptor.\n");
+
+ return R_FAILURE;
+ }
+
+ if (scene_desc_len != SAGA_SCENE_DESC_LEN) {
+ R_printf(R_STDERR,
+ "Error: scene descriptor length invalid.\n");
+
+ return R_FAILURE;
+ }
+
+ read_p = scene_desc_data;
+
+ SceneModule.desc.unknown0 = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.res_list_rn = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.end_slope = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.begin_slope = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.script_num = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.scene_scriptnum = ys_read_u16_le(read_p, &read_p);
+ SceneModule.desc.start_scriptnum = ys_read_u16_le(read_p, &read_p);
+
+ SceneModule.desc.music_rn = ys_read_s16_le(read_p, &read_p);
+
+ RSC_FreeResource(scene_desc_data);
+
+ return R_SUCCESS;
+}
+
+int LoadSceneResourceList(ulong reslist_rn)
+{
+
+ uchar *resource_list;
+ size_t resource_list_len;
+
+ const uchar *read_p;
+
+ int result;
+ int i;
+
+ /*
+ * Load the scene resource table
+ \*-------------------------------------------------------------*/
+ result = RSC_LoadResource(SceneModule.scene_ctxt,
+ reslist_rn, &resource_list, &resource_list_len);
+ if (result != R_SUCCESS) {
+
+ R_printf(R_STDERR,
+ "Error: couldn't load scene resource list.\n");
+
+ return R_FAILURE;
+ }
+
+ read_p = resource_list;
+
+ /* Allocate memory for scene resource list
+ * \*----------------------------------------- */
+ SceneModule.reslist_entries =
+ resource_list_len / SAGA_RESLIST_ENTRY_LEN;
+
+ R_printf(R_STDOUT,
+ "Scene resource list contains %d entries.\n",
+ SceneModule.reslist_entries);
+
+ SceneModule.reslist =
+ (R_SCENE_RESLIST *)calloc(SceneModule.reslist_entries, sizeof *SceneModule.reslist);
+
+ if (SceneModule.reslist == NULL) {
+ R_printf(R_STDERR, "Error: Memory allocation failed.\n");
+
+ return R_MEM;
+ }
+
+ /* Load scene resource list from raw scene
+ * resource table
+ \*-----------------------------------------*/
+ R_printf(R_STDOUT, "Loading scene resource list...\n");
+
+ for (i = 0; i < SceneModule.reslist_entries; i++) {
+
+ SceneModule.reslist[i].res_number =
+ ys_read_u16_le(read_p, &read_p);
+ SceneModule.reslist[i].res_type =
+ ys_read_u16_le(read_p, &read_p);
+ }
+
+ RSC_FreeResource(resource_list);
+
+ return R_SUCCESS;
+}
+
+int ProcessSceneResources(void)
+{
+
+ const uchar *res_data;
+ size_t res_data_len;
+
+ const uchar *pal_p;
+
+ int i;
+
+ /*
+ * Process the scene resource list
+ \*-------------------------------------------------------------*/
+ for (i = 0; i < SceneModule.reslist_entries; i++) {
+
+ res_data = SceneModule.reslist[i].res_data;
+ res_data_len = SceneModule.reslist[i].res_data_len;
+
+ switch (SceneModule.reslist[i].res_type) {
+
+ /* Scene background resource */
+ case SAGA_BG_IMAGE:
+
+ if (SceneModule.bg.loaded) {
+
+ R_printf(R_STDERR,
+ "Error: Multiple background resources "
+ "encountered.\n");
+ return R_FAILURE;
+ }
+
+ R_printf(R_STDOUT, "Loading background resource.\n");
+
+ SceneModule.bg.res_buf =
+ SceneModule.reslist[i].res_data;
+ SceneModule.bg.res_len =
+ SceneModule.reslist[i].res_data_len;
+ SceneModule.bg.loaded = 1;
+
+ if (IMG_DecodeBGImage(SceneModule.bg.res_buf,
+ SceneModule.bg.res_len,
+ &SceneModule.bg.buf,
+ &SceneModule.bg.buf_len,
+ &SceneModule.bg.w,
+ &SceneModule.bg.h) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error loading background resource: %lu\n",
+ SceneModule.reslist[i].res_number);
+
+ return R_FAILURE;
+ }
+
+ pal_p = IMG_GetImagePal(SceneModule.bg.res_buf,
+ SceneModule.bg.res_len);
+
+ memcpy(SceneModule.bg.pal,
+ pal_p, sizeof SceneModule.bg.pal);
+
+ SceneModule.scene_mode = R_SCENE_MODE_NORMAL;
+
+ break;
+
+ /* Scene background mask resource */
+ case SAGA_BG_MASK:
+
+ if (SceneModule.bg_mask.loaded) {
+ R_printf(R_STDERR,
+ "Error: Duplicate background mask resource "
+ "encountered.\n");
+ }
+
+ R_printf(R_STDOUT,
+ "Loading BACKGROUND MASK resource.\n");
+
+ SceneModule.bg_mask.res_buf =
+ SceneModule.reslist[i].res_data;
+ SceneModule.bg_mask.res_len =
+ SceneModule.reslist[i].res_data_len;
+ SceneModule.bg_mask.loaded = 1;
+
+ IMG_DecodeBGImage(SceneModule.bg_mask.res_buf,
+ SceneModule.bg_mask.res_len,
+ &SceneModule.bg_mask.buf,
+ &SceneModule.bg_mask.buf_len,
+ &SceneModule.bg_mask.w, &SceneModule.bg_mask.h);
+ break;
+
+ case SAGA_OBJECT_NAME_LIST:
+
+ R_printf(R_STDOUT,
+ "Loading object name list resource...\n");
+
+ OBJECTMAP_LoadNames(SceneModule.reslist[i].res_data,
+ SceneModule.reslist[i].res_data_len);
+ break;
+
+ case SAGA_OBJECT_MAP:
+
+ R_printf(R_STDOUT, "Loading object map resource...\n");
+
+ if (OBJECTMAP_Load(res_data,
+ res_data_len) != R_SUCCESS) {
+
+ R_printf(R_STDERR,
+ "Error loading object map resource.\n");
+ return R_FAILURE;
+ }
+ break;
+
+ case SAGA_ACTION_MAP:
+
+ R_printf(R_STDOUT, "Loading exit map resource...\n");
+
+ if (ACTIONMAP_Load(res_data,
+ res_data_len) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error loading exit map resource.\n");
+ return R_FAILURE;
+ }
+ break;
+
+ case SAGA_ISO_TILESET:
+
+ if (SceneModule.scene_mode == R_SCENE_MODE_NORMAL) {
+ R_printf(R_STDERR,
+ "Isometric tileset incompatible with normal "
+ "scene mode.\n");
+ return R_FAILURE;
+ }
+
+ R_printf(R_STDOUT,
+ "Loading isometric tileset resource.\n");
+
+ if (ISOMAP_LoadTileset(res_data,
+ res_data_len) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error loading isometric tileset resource.\n");
+ return R_FAILURE;
+ }
+
+ SceneModule.scene_mode = R_SCENE_MODE_ISO;
+ break;
+
+ case SAGA_ISO_METAMAP:
+
+ if (SceneModule.scene_mode == R_SCENE_MODE_NORMAL) {
+ R_printf(R_STDERR,
+ "Isometric metamap incompatible with normal "
+ "scene mode.\n");
+ return R_FAILURE;
+ }
+
+ R_printf(R_STDOUT,
+ "Loading isometric metamap resource.\n");
+
+ if (ISOMAP_LoadMetamap(res_data,
+ res_data_len) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error loading isometric metamap resource.\n");
+ return R_FAILURE;
+ }
+
+ SceneModule.scene_mode = R_SCENE_MODE_ISO;
+ break;
+
+ case SAGA_ISO_METATILESET:
+ if (SceneModule.scene_mode == R_SCENE_MODE_NORMAL) {
+ R_printf(R_STDERR,
+ "Isometric metatileset incompatible with "
+ "normal scene mode.\n");
+ return R_FAILURE;
+ }
+
+ R_printf(R_STDOUT,
+ "Loading isometric metatileset resource.\n");
+
+ if (ISOMAP_LoadMetaTileset(res_data,
+ res_data_len) != R_SUCCESS) {
+ R_printf(R_STDERR,
+ "Error loading isometric tileset resource.\n");
+ return R_FAILURE;
+ }
+
+ SceneModule.scene_mode = R_SCENE_MODE_ISO;
+ break;
+
+ case SAGA_ANIM_1:
+ case SAGA_ANIM_2:
+ case SAGA_ANIM_3:
+ case SAGA_ANIM_4:
+ case SAGA_ANIM_5:
+ case SAGA_ANIM_6:
+ case SAGA_ANIM_7:
+ {
+ SCENE_ANIMINFO *new_animinfo;
+ uint new_anim_id;
+
+ R_printf(R_STDOUT,
+ "Loading animation resource...\n");
+
+ new_animinfo = (SCENE_ANIMINFO *)malloc(sizeof *new_animinfo);
+ if (new_animinfo == NULL) {
+
+ R_printf(R_STDERR,
+ "Memory allocation error.\n");
+
+ return R_MEM;
+ }
+
+ if (ANIM_Load(SceneModule.reslist[i].res_data,
+ SceneModule.reslist[i].res_data_len,
+ &new_anim_id) == R_SUCCESS) {
+ } else {
+ R_printf(R_STDERR,
+ "Error loading animation resource\n");
+
+ return R_FAILURE;
+ }
+
+ new_animinfo->anim_handle = new_anim_id;
+ new_animinfo->anim_res_number =
+ SceneModule.reslist[i].res_number;
+
+ ys_dll_add_tail(SceneModule.anim_list,
+ new_animinfo, sizeof *new_animinfo);
+
+ SceneModule.anim_entries++;
+ }
+ break;
+
+ case SAGA_PAL_ANIM:
+
+ R_printf(R_STDOUT,
+ "Loading palette animation resource.\n");
+
+ PALANIM_Load(SceneModule.reslist[i].res_data,
+ SceneModule.reslist[i].res_data_len);
+ break;
+
+ default:
+
+ R_printf(R_STDERR,
+ "Encountered unknown resource type: %d\n",
+ SceneModule.reslist[i].res_type);
+ break;
+
+ }
+ }
+
+ return R_SUCCESS;
+}
+
+int SCENE_Draw(R_SURFACE * dst_s)
+{
+ R_GAME_DISPLAYINFO disp_info;
+ R_BUFFER_INFO buf_info;
+ R_POINT bg_pt;
+
+ assert(SceneModule.init);
+
+ RENDER_GetBufferInfo(&buf_info);
+ GAME_GetDisplayInfo(&disp_info);
+
+ bg_pt.x = 0;
+ bg_pt.y = 0;
+
+ switch (SceneModule.scene_mode) {
+
+ case R_SCENE_MODE_NORMAL:
+
+ GFX_BufToSurface(dst_s,
+ buf_info.r_bg_buf,
+ disp_info.logical_w,
+ YS_MAX(disp_info.scene_h, SceneModule.bg.h), NULL, &bg_pt);
+ break;
+
+ case R_SCENE_MODE_ISO:
+
+ ISOMAP_Draw(dst_s);
+ break;
+
+ default:
+ /* Unknown scene mode */
+ return R_FAILURE;
+ break;
+
+ };
+
+ return R_SUCCESS;
+}
+
+int SCENE_End(void)
+{
+ R_SCENE_INFO scene_info;
+
+ assert(SceneModule.init);
+
+ if (SceneModule.scene_loaded != 1) {
+ R_printf(R_STDERR, "SCENE_End(): No scene to end.\n");
+ return -1;
+ }
+
+ R_printf(R_STDOUT, "SCENE_End(): Ending scene...\n");
+
+ SCENE_GetInfo(&scene_info);
+
+ SceneModule.scene_proc(SCENE_END, &scene_info);
+
+ if (SceneModule.desc.script_num > 0) {
+
+ SCRIPT_Free();
+ }
+
+ /* Free scene background */
+ if (SceneModule.bg.loaded) {
+ free(SceneModule.bg.buf);
+ SceneModule.bg.loaded = 0;
+ }
+
+ /* Free scene background mask */
+ if (SceneModule.bg_mask.loaded) {
+ free(SceneModule.bg_mask.buf);
+ SceneModule.bg_mask.loaded = 0;
+ }
+
+ /* Free scene resource list */
+ if (SceneModule.load_desc) {
+
+ free(SceneModule.reslist);
+ }
+
+ /* Free animation info list */
+ ANIM_Reset();
+
+ PALANIM_Free();
+ OBJECTMAP_Free();
+ ACTIONMAP_Free();
+
+ ys_dll_destroy(SceneModule.anim_list);
+
+ SceneModule.anim_entries = 0;
+
+ EVENT_ClearList();
+ TEXT_ClearList(SceneModule.text_list);
+
+ SceneModule.scene_loaded = 0;
+
+ return R_SUCCESS;
+}
+
+void CF_scenechange(int argc, char *argv[])
+{
+
+ int scene_num = 0;
+
+ if ((argc == 0) || (argc > 1)) {
+ return;
+ }
+
+ scene_num = atoi(argv[0]);
+
+ if ((scene_num < 1) || (scene_num > SceneModule.scene_max)) {
+ CON_Print("Invalid scene number.");
+ return;
+ }
+
+ SCENE_ClearQueue();
+
+ if (SCENE_Change(scene_num) == R_SUCCESS) {
+ CON_Print("Scene changed.");
+ } else {
+ CON_Print("Couldn't change scene!");
+ }
+
+ return;
+}
+
+void CF_sceneinfo(int argc, char *argv[])
+{
+
+ const char *fmt = "%-20s %d";
+
+ YS_IGNORE_PARAM(argc);
+ YS_IGNORE_PARAM(argv);
+
+ CON_Print(fmt, "Scene number:", SceneModule.scene_number);
+ CON_Print(fmt, "Descriptor R#:", SceneModule.scene_rn);
+ CON_Print("-------------------------");
+ CON_Print(fmt, "Unknown:", SceneModule.desc.unknown0);
+ CON_Print(fmt, "Resource list R#:", SceneModule.desc.res_list_rn);
+ CON_Print(fmt, "End slope:", SceneModule.desc.end_slope);
+ CON_Print(fmt, "Begin slope:", SceneModule.desc.begin_slope);
+ CON_Print(fmt, "Script resource:", SceneModule.desc.script_num);
+ CON_Print(fmt, "Scene script:", SceneModule.desc.scene_scriptnum);
+ CON_Print(fmt, "Start script:", SceneModule.desc.start_scriptnum);
+ CON_Print(fmt, "Music R#", SceneModule.desc.music_rn);
+
+ return;
+}
+
+} // End of namespace Saga