aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2019-05-11 19:20:40 +1000
committerPaul Gilbert2019-05-12 10:19:48 +1000
commit6b6670caf9812a980a9aa4049bf6931aa943b79b (patch)
treecdd84119c95fcda75a385f8e3e14844392c58ca4 /engines
parent98f6315366eafc0568d46ee4d9cba8d0d6495950 (diff)
downloadscummvm-rg350-6b6670caf9812a980a9aa4049bf6931aa943b79b.tar.gz
scummvm-rg350-6b6670caf9812a980a9aa4049bf6931aa943b79b.tar.bz2
scummvm-rg350-6b6670caf9812a980a9aa4049bf6931aa943b79b.zip
GLK: HUGO: Added hemedia & heres
Diffstat (limited to 'engines')
-rw-r--r--engines/glk/hugo/hemedia.cpp204
-rw-r--r--engines/glk/hugo/heparse.cpp4
-rw-r--r--engines/glk/hugo/heres.cpp472
-rw-r--r--engines/glk/hugo/hugo.cpp12
-rw-r--r--engines/glk/hugo/hugo.h100
-rw-r--r--engines/glk/hugo/hugo_defines.h13
-rw-r--r--engines/glk/hugo/hugo_types.h13
-rw-r--r--engines/glk/module.mk2
8 files changed, 807 insertions, 13 deletions
diff --git a/engines/glk/hugo/hemedia.cpp b/engines/glk/hugo/hemedia.cpp
new file mode 100644
index 0000000000..19c9874ed4
--- /dev/null
+++ b/engines/glk/hugo/hemedia.cpp
@@ -0,0 +1,204 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/hugo/hugo.h"
+
+namespace Glk {
+namespace Hugo {
+
+int Hugo::loadres(HUGO_FILE infile, int reslen, int type) {
+ char buf[4096];
+ frefid_t fileref;
+ strid_t stream;
+ long offset;
+ int idVal;
+ int i, n;
+
+ offset = hugo_ftell(infile);
+ for (i = 0; i < numres[type]; i++)
+ if (resids[type][i] == offset)
+ return i;
+
+ /* Too many resources loaded... */
+ if (numres[type] + 1 == MAXRES)
+ return -1;
+
+ idVal = numres[type]++;
+ sprintf(buf, "%s%d", type == PIC ? "PIC" : "SND", idVal);
+ resids[type][idVal] = offset;
+
+ fileref = glk_fileref_create_by_name(fileusage_Data, buf, 0);
+ if (!fileref)
+ {
+ return -1;
+ }
+
+ stream = glk_stream_open_file(fileref, filemode_Write, 0);
+ if (!stream)
+ {
+ glk_fileref_destroy(fileref);
+ return -1;
+ }
+
+ glk_fileref_destroy(fileref);
+
+ while (reslen > 0)
+ {
+ n = hugo_fread(buf, 1, reslen < sizeof buf ? reslen : sizeof buf, infile);
+ if (n <= 0)
+ break;
+ glk_put_buffer_stream(stream, buf, n);
+ reslen -= n;
+ }
+
+ glk_stream_close(stream, NULL);
+
+ return idVal;
+}
+
+int Hugo::hugo_hasgraphics() {
+ /* Returns true if the current display is capable of graphics display */
+ return glk_gestalt(gestalt_Graphics, 0)
+ && glk_gestalt(gestalt_DrawImage, glk_window_get_type(mainwin));
+}
+
+int Hugo::hugo_displaypicture(HUGO_FILE infile, long reslen) {
+ int idVal;
+
+ /* Ignore the call if the current window is set elsewhere. */
+ if (currentwin != NULL && currentwin != mainwin)
+ {
+ hugo_fclose(infile);
+ return false;
+ }
+
+ idVal = loadres(infile, reslen, PIC);
+ if (idVal < 0)
+ {
+ hugo_fclose(infile);
+ return false;
+ }
+
+#if 0
+ /* Get picture width and height for scaling. */
+ glui32 width, height;
+ if (glk_image_get_info(idVal, &width, &height))
+ {
+ /* Scale large images. */
+ if (width > PIC_MAX_WIDTH)
+ {
+ height = height * PIC_MAX_WIDTH / width;
+ width = PIC_MAX_WIDTH;
+ }
+ if (height > PIC_MAX_HEIGHT)
+ {
+ width = width * PIC_MAX_HEIGHT / height;
+ height = PIC_MAX_HEIGHT;
+ }
+ }
+#endif
+
+ hugo_fclose(infile);
+
+ /* Draw, then move cursor down to the next line. */
+ glk_image_draw(mainwin, idVal, imagealign_InlineUp, 0);
+ glk_put_char('\n');
+
+ return true;
+}
+
+void Hugo::initsound() {
+ if (!glk_gestalt(gestalt_Sound, 0))
+ return;
+ schannel = glk_schannel_create(0);
+}
+
+void Hugo::initmusic() {
+ if (!glk_gestalt(gestalt_Sound, 0) || !glk_gestalt(gestalt_SoundMusic, 0))
+ return;
+ mchannel = glk_schannel_create(0);
+}
+
+int Hugo::hugo_playmusic(HUGO_FILE infile, long reslen, char loop_flag) {
+ int idVal;
+
+ if (!mchannel)
+ initmusic();
+ if (mchannel)
+ {
+ idVal = loadres(infile, reslen, SND);
+ if (idVal < 0)
+ {
+ hugo_fclose(infile);
+ return false;
+ }
+ glk_schannel_play_ext(mchannel, idVal, loop_flag ? -1 : 1, 0);
+ }
+
+ hugo_fclose(infile);
+ return true;
+}
+
+void Hugo::hugo_musicvolume(int vol) {
+ if (!mchannel) initmusic();
+ if (!mchannel) return;
+ glk_schannel_set_volume(mchannel, (vol * 0x10000) / 100);
+}
+
+void Hugo::hugo_stopmusic() {
+ if (!mchannel) initmusic();
+ if (!mchannel) return;
+ glk_schannel_stop(mchannel);
+}
+
+int Hugo::hugo_playsample(HUGO_FILE infile, long reslen, char loop_flag) {
+ int idVal;
+
+ if (schannel)
+ {
+ idVal = loadres(infile, reslen, SND);
+ if (idVal < 0)
+ {
+ hugo_fclose(infile);
+ return false;
+ }
+ glk_schannel_play_ext(schannel, idVal, loop_flag ? -1 : 1, 0);
+ }
+
+ hugo_fclose(infile);
+ return true;
+}
+
+void Hugo::hugo_samplevolume(int vol) {
+ if (!schannel) initsound();
+ if (!schannel) return;
+ glk_schannel_set_volume(schannel, (vol * 0x10000) / 100);
+}
+
+void Hugo::hugo_stopsample() {
+ if (!schannel) initsound();
+ if (!schannel) return;
+ glk_schannel_stop(schannel);
+}
+
+} // End of namespace Hugo
+} // End of namespace Glk
diff --git a/engines/glk/hugo/heparse.cpp b/engines/glk/hugo/heparse.cpp
index 0369385398..da01810a8e 100644
--- a/engines/glk/hugo/heparse.cpp
+++ b/engines/glk/hugo/heparse.cpp
@@ -2104,8 +2104,8 @@ NextSyn:
{
if (strcmp(word[i+1], "~and"))
{
- static char *END = "~and";
- word[i] = END;
+ static char AND[5] = "~and";
+ word[i] = AND;
wd[i] = FindWord("~and");
}
else
diff --git a/engines/glk/hugo/heres.cpp b/engines/glk/hugo/heres.cpp
new file mode 100644
index 0000000000..606f712f0c
--- /dev/null
+++ b/engines/glk/hugo/heres.cpp
@@ -0,0 +1,472 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/hugo/hugo.h"
+
+namespace Glk {
+namespace Hugo {
+
+void Hugo::DisplayPicture() {
+ char filename[MAX_RES_PATH], resname[MAX_RES_PATH];
+ long reslength;
+
+ GetResourceParameters(filename, resname, PICTURE_T);
+
+ if (!hugo_hasgraphics())
+ {
+ var[system_status] = STAT_UNAVAILABLE;
+ return;
+ }
+
+ /* If filename is empty, no resource file was specified and
+ the line[] array simply holds the path of the file to be loaded
+ as a resource
+ */
+ if (!(reslength = FindResource(filename, resname)))
+ return;
+
+ /* Find out what type of image resource this is */
+ resource_type = (char)((hugo_fgetc(resource_file)==0xff) ? JPEG_R : UNKNOWN_R);
+ hugo_fseek(resource_file, -1, SEEK_CUR);
+
+ /* If FindResource() is successful, the resource file is already
+ open and positioned; hugo_displaypicture() is responsible for
+ closing resource_file before returning regardless of success
+ or failure
+ */
+ if (!hugo_displaypicture(resource_file, reslength))
+ var[system_status] = STAT_LOADERROR;
+}
+
+void Hugo::PlayMusic() {
+ char filename[MAX_RES_PATH], resname[MAX_RES_PATH];
+ char loop_flag = 0;
+ long resstart, reslength;
+
+ if (MEM(codeptr+1)==REPEAT_T) loop_flag = true, codeptr++;
+
+ hugo_stopmusic();
+
+ /* If a 0 parameter is passed, i.e. "music 0" */
+ if (!GetResourceParameters(filename, resname, MUSIC_T))
+ {
+ return;
+ }
+
+ if (extra_param>=0)
+ {
+ if (extra_param > 100) extra_param = 100;
+ hugo_musicvolume(extra_param);
+ }
+
+ if (!(reslength = FindResource(filename, resname)))
+ return;
+
+ /* Find out what type of music resource this is */
+ resstart = hugo_ftell(resource_file);
+
+ /* Check for MIDI */
+ hugo_fseek(resource_file, resstart, SEEK_SET);
+ hugo_fread(resname, 4, 1, resource_file);
+ if (!memcmp(resname, "MThd", 4))
+ {
+ resource_type = MIDI_R;
+ goto Identified;
+ }
+
+ /* Check for XM */
+ hugo_fseek(resource_file, resstart, SEEK_SET);
+ hugo_fread(resname, 17, 1, resource_file);
+ if (!memcmp(resname, "Extended Module: ", 17))
+ {
+ resource_type = XM_R;
+ goto Identified;
+ }
+
+ /* Check for S3M */
+ hugo_fseek(resource_file, resstart+0x2c, SEEK_SET);
+ hugo_fread(resname, 4, 1, resource_file);
+ if (!memcmp(resname, "SCRM", 4))
+ {
+ resource_type = S3M_R;
+ goto Identified;
+ }
+
+ /* Check for MOD */
+ hugo_fseek(resource_file, resstart+1080, SEEK_SET);
+ hugo_fread(resname, 4, 1, resource_file);
+ resname[4] = '\0';
+ /* There are a whole bunch of different MOD identifiers: */
+ if (!strcmp(resname+1, "CHN") || /* 4CHN, 6CHN, 8CHN */
+ !strcmp(resname+2, "CN") || /* 16CN, 32CN */
+ !strcmp(resname, "M.K.") || !strcmp(resname, "M!K!") ||
+ !strcmp(resname, "FLT4") || !strcmp(resname, "CD81") ||
+ !strcmp(resname, "OKTA") || !strcmp(resname, " "))
+ {
+ resource_type = MOD_R;
+ goto Identified;
+ }
+
+ /* Check for MP3 */
+/* Assume for now that otherwise unidentified is MP3 */
+ else
+ {
+ resource_type = MP3_R;
+ goto Identified;
+ }
+
+ /* No file type identified */
+ resource_type = UNKNOWN_R;
+
+Identified:
+ hugo_fseek(resource_file, resstart, SEEK_SET);
+
+ if (!hugo_playmusic(resource_file, reslength, loop_flag))
+ var[system_status] = STAT_LOADERROR;
+}
+
+void Hugo::PlaySample() {
+ char filename[MAX_RES_PATH], resname[MAX_RES_PATH];
+ char loop_flag = 0;
+ long reslength;
+
+ if (MEM(codeptr+1)==REPEAT_T) loop_flag = true, codeptr++;
+
+ hugo_stopsample();
+
+ /* If a 0 parameter is passed, i.e. "sound 0" */
+ if (!GetResourceParameters(filename, resname, SOUND_T))
+ {
+ return;
+ }
+
+ if (extra_param>=0)
+ {
+ if (extra_param > 100) extra_param = 100;
+ hugo_samplevolume(extra_param);
+ }
+
+ if (!(reslength = FindResource(filename, resname)))
+ return;
+
+ /* Find out what kind of audio sample this is */
+ hugo_fread(resname, 4, 1, resource_file);
+ if (!memcmp(resname, "WAVE", 4))
+ resource_type = WAVE_R;
+ else
+ resource_type = UNKNOWN_R;
+
+ hugo_fseek(resource_file, -4, SEEK_CUR);
+
+ if (!hugo_playsample(resource_file, reslength, loop_flag))
+ var[system_status] = STAT_LOADERROR;
+}
+
+void Hugo::PlayVideo() {
+ char filename[MAX_RES_PATH], resname[MAX_RES_PATH];
+ char loop_flag = 0, background = 0;
+ int volume = 100;
+ long resstart, reslength;
+
+#if defined (COMPILE_V25)
+ var[system_status] = STAT_UNAVAILABLE;
+#endif
+ if (MEM(codeptr+1)==REPEAT_T) loop_flag = true, codeptr++;
+
+#if !defined (COMPILE_V25)
+ hugo_stopvideo();
+#endif
+
+ /* If a 0 parameter is passed, i.e. "video 0" */
+ if (!GetResourceParameters(filename, resname, VIDEO_T))
+ {
+ return;
+ }
+
+ if (MEM(codeptr-1)==COMMA_T)
+ {
+ background = (char)GetValue();
+ codeptr++; /* eol */
+ }
+
+ if (extra_param>=0)
+ {
+ if (extra_param > 100) extra_param = 100;
+ volume = extra_param;
+ }
+
+ if (!(reslength = FindResource(filename, resname)))
+ return;
+
+ /* Find out what type of video resource this is */
+ resstart = hugo_ftell(resource_file);
+
+ /* Check for MPEG */
+ hugo_fseek(resource_file, resstart, SEEK_SET);
+ hugo_fread(resname, 4, 1, resource_file);
+ if (resname[2]==0x01 && (unsigned char)resname[3]==0xba)
+ {
+ resource_type = MPEG_R;
+ goto Identified;
+ }
+
+ /* Check for AVI */
+ hugo_fseek(resource_file, resstart+8, SEEK_SET);
+ hugo_fread(resname, 4, 1, resource_file);
+ if (!memcmp(resname, "AVI ", 4))
+ {
+ resource_type = AVI_R;
+ goto Identified;
+ }
+
+ /* No file type identified */
+ resource_type = UNKNOWN_R;
+
+Identified:
+ hugo_fseek(resource_file, resstart, SEEK_SET);
+
+#if !defined (COMPILE_V25)
+ if (!hugo_playvideo(resource_file, reslength, loop_flag, background, volume))
+ var[system_status] = STAT_LOADERROR;
+#else
+ fclose(resource_file);
+ resource_file = nullptr;
+#endif
+}
+
+long Hugo::FindResource(char *filename, char *resname) {
+ char resource_in_file[MAX_RES_PATH];
+ int i, len;
+ int rescount;
+ unsigned int startofdata;
+ long resposition, reslength;
+#if defined (GLK)
+ frefid_t fref;
+#endif
+/* Previously, resource positions were written as 24 bits, which meant that
+ a given resource couldn't start after 16,777,216 bytes or be more than
+ that length. The new resource file format (designated by 'r') corrects this. */
+ int res_32bits = true;
+
+ resource_file = nullptr;
+
+ strcpy(loaded_filename, filename);
+ strcpy(loaded_resname, resname);
+ if (!strcmp(filename, "")) strcpy(loaded_filename, resname);
+
+ /* See if the file is supposed to be in a resourcefile to
+ begin with
+ */
+ if (!strcmp(filename, ""))
+ goto NotinResourceFile;
+
+
+ /* Open the resourcefile */
+ strupr(filename);
+
+#if !defined (GLK)
+ /* stdio implementation */
+ if (!(resource_file = TrytoOpen(filename, "rb", "games")))
+ if (!(resource_file = TrytoOpen(filename, "rb", "object")))
+ {
+ var[system_status] = STAT_NOFILE;
+ return 0;
+ }
+#else
+ /* Glk implementation */
+ fref = glk_fileref_create_by_name(fileusage_Data | fileusage_BinaryMode,
+ filename, 0);
+ if (glk_fileref_does_file_exist(fref))
+ resource_file = glk_stream_open_file(fref, filemode_Read, 0);
+ else
+ resource_file = nullptr;
+ glk_fileref_destroy(fref);
+ if (!resource_file)
+ {
+ var[system_status] = STAT_NOFILE;
+ return 0;
+ }
+#endif
+
+ /* Read the resourcefile header */
+ /* if (fgetc(resource_file)!='R') goto ResfileError; */
+ i = hugo_fgetc(resource_file);
+ if (i=='r')
+ res_32bits = true;
+ else if (i=='R')
+ res_32bits = false;
+ else
+ goto ResfileError;
+ /* Read and ignore the resource file version. */
+ hugo_fgetc(resource_file);
+ rescount = hugo_fgetc(resource_file);
+ rescount += hugo_fgetc(resource_file)*256;
+ startofdata = hugo_fgetc(resource_file);
+ startofdata += (unsigned int)hugo_fgetc(resource_file)*256;
+ if (hugo_ferror(resource_file))
+ goto ResfileError;
+
+
+ /* Now skim through the list of resources in the resourcefile to
+ see if we have a match
+ */
+ for (i=1; i<=rescount; i++)
+ {
+ len = hugo_fgetc(resource_file);
+ if (hugo_ferror(resource_file))
+ goto ResfileError;
+
+ if (!(hugo_fgets(resource_in_file, len+1, resource_file)))
+ goto ResfileError;
+
+ resposition = (long)hugo_fgetc(resource_file);
+ resposition += (long)hugo_fgetc(resource_file)*256L;
+ resposition += (long)hugo_fgetc(resource_file)*65536L;
+ if (res_32bits)
+ {
+ resposition += (long)hugo_fgetc(resource_file)*16777216L;
+ }
+
+ reslength = (long)hugo_fgetc(resource_file);
+ reslength += (long)hugo_fgetc(resource_file)*256L;
+ reslength += (long)hugo_fgetc(resource_file)*65536L;
+ if (res_32bits)
+ {
+ reslength += (long)hugo_fgetc(resource_file)*16777216L;
+ }
+ if (hugo_ferror(resource_file)) goto ResfileError;
+
+ if (!strcmp(resname, resource_in_file))
+ {
+ if (hugo_fseek(resource_file, (long)startofdata+resposition, SEEK_SET))
+ goto ResfileError;
+ return reslength;
+ }
+ }
+
+ResfileError:
+
+ var[system_status] = STAT_NORESOURCE;
+
+#if defined (DEBUGGER)
+ SwitchtoDebugger();
+ sprintf(debug_line, "Unable to find \"%s\" in \"%s\"", resname, filename);
+ DebugMessageBox("Resource Error", debug_line);
+ SwitchtoGame();
+#endif
+ hugo_fclose(resource_file);
+ resource_file = nullptr;
+
+
+ /* If we get here, we've either been unable to find the named
+ resource in the given resourcefile, or no resourcefile was
+ given
+ */
+NotinResourceFile:
+
+#if !defined (GLK)
+ /* stdio implementation */
+ if (!(resource_file = TrytoOpen(resname, "rb", "resource")))
+ if (!(resource_file = TrytoOpen(resname, "rb", "source")))
+ {
+ if (!strcmp(filename, ""))
+ var[system_status] = STAT_NOFILE;
+ else
+ var[system_status] = STAT_NORESOURCE;
+ return 0;
+ }
+#else
+ /* Glk implementation */
+ fref = glk_fileref_create_by_name(fileusage_Data | fileusage_BinaryMode,
+ resname, 0);
+ if (glk_fileref_does_file_exist(fref))
+ resource_file = glk_stream_open_file(fref, filemode_Read, 0);
+ else
+ resource_file = nullptr;
+ glk_fileref_destroy(fref);
+ if (!resource_file)
+ {
+ if (!strcmp(filename, ""))
+ var[system_status] = STAT_NOFILE;
+ else
+ var[system_status] = STAT_NORESOURCE;
+ return 0;
+ }
+#endif
+
+ /* resource_file here refers to a resource in an individual
+ on-disk file, not a consolidated resource file
+ */
+ hugo_fseek(resource_file, 0, SEEK_END);
+ reslength = hugo_ftell(resource_file);
+ hugo_fseek(resource_file, 0, SEEK_SET);
+ if (hugo_ferror(resource_file))
+ {
+ hugo_fclose(resource_file);
+ resource_file = nullptr;
+ return false;
+ }
+
+ return reslength;
+}
+
+int Hugo::GetResourceParameters(char *filename, char *resname, int restype) {
+ int f;
+
+ var[system_status] = 0;
+
+ extra_param = -1;
+
+ codeptr++; /* token--i.e., 'picture', etc. */
+
+ f = GetValue();
+
+ /* If a 0 parameter is passed for "music 0", etc. */
+ if (!f && MEM(codeptr)!=COMMA_T)
+ {
+ ++codeptr;
+ return 0;
+ }
+
+ strcpy(filename, GetWord((unsigned int)f));
+
+ if (MEM(codeptr++)!=EOL_T) /* two or more parameters */
+ {
+ strupr(filename);
+ strcpy(resname, GetWord(GetValue()));
+ if (MEM(codeptr++)==COMMA_T)
+ {
+ extra_param = GetValue();
+ codeptr++;
+ }
+ }
+ else /* only one parameter */
+ {
+ strcpy(resname, filename);
+ strcpy(filename, "");
+ }
+
+ return true;
+}
+
+} // End of namespace Hugo
+} // End of namespace Glk
diff --git a/engines/glk/hugo/hugo.cpp b/engines/glk/hugo/hugo.cpp
index bd8575b080..8d85c68606 100644
--- a/engines/glk/hugo/hugo.cpp
+++ b/engines/glk/hugo/hugo.cpp
@@ -31,6 +31,8 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
SCREENWIDTH(0), SCREENHEIGHT(0), FIXEDCHARWIDTH(0), FIXEDLINEHEIGHT(0),
// heexpr
evalcount(0), incdec(0), getaddress(0), inexpr(0), inobj(0),
+ // hemedia
+ mchannel(nullptr), schannel(nullptr),
// hemisc
game_version(0), object_size(0), game(nullptr), script(nullptr), save(nullptr),
playback(nullptr), record(nullptr), io(nullptr), ioblock('\0'), ioerror('\0'),
@@ -56,6 +58,8 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
objgrammar(0), objstart(0), objfinish(0), addflag(false), speaking(0), oopscount(0),
parse_called_twice(0), reparse_everything(0), full_buffer(false), recursive_call(false),
parse_location(0),
+ // heres
+ resource_file(nullptr), extra_param(0), resource_type(0),
// herun
arguments_passed(0), ret(0), retflag(0), during_player_input(false), override_full(0),
game_reset(false), stack_depth(0), tail_recursion(0), tail_recursion_addr(0),
@@ -78,6 +82,10 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
Common::fill(&eval[0], &eval[MAX_EVAL_ELEMENTS], 0);
Common::fill(&var[0], &var[MAXLOCALS + MAXGLOBALS], 0);
+ // hemedia
+ Common::fill(&resids[0][0], &resids[2][MAXRES], 0);
+ numres[0] = numres[1] = 0;
+
// hemisc
Common::fill(&context_command[0][0], &context_command[MAX_CONTEXT_COMMANDS][64], 0);
Common::fill(&id[0], &id[3], '\0');
@@ -98,6 +106,10 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
Common::fill(&oops[0], &oops[MAXBUFFER + 1], '\0');
Common::fill(&punc_string[0], &punc_string[64], '\0');
+ // heres
+ Common::fill(&loaded_filename[0], &loaded_filename[MAX_RES_PATH], '\0');
+ Common::fill(&loaded_resname[0], &loaded_resname[MAX_RES_PATH], '\0');
+
// herun
Common::fill(&passlocal[0], &passlocal[MAXLOCALS], 0);
diff --git a/engines/glk/hugo/hugo.h b/engines/glk/hugo/hugo.h
index eeb65a29be..8d2d18b749 100644
--- a/engines/glk/hugo/hugo.h
+++ b/engines/glk/hugo/hugo.h
@@ -62,12 +62,16 @@ private:
int last_precedence;
+ // hemedia
+ schanid_t mchannel;
+ schanid_t schannel;
+ long resids[2][MAXRES];
+ int numres[2];
// hemisc
char gamefile[255];
int game_version;
int object_size;
- //HUGO_FILE game;
Common::SeekableReadStream *game;
HUGO_FILE script;
HUGO_FILE save;
@@ -188,6 +192,13 @@ private:
char recursive_call;
int parse_location; ///< usually var[location]
+ // heres
+ HUGO_FILE resource_file;
+ int extra_param;
+ char loaded_filename[MAX_RES_PATH];
+ char loaded_resname[MAX_RES_PATH];
+ char resource_type = 0;
+
// herun
int passlocal[MAXLOCALS]; ///< locals passed to routine
int arguments_passed; ///< when calling routine
@@ -619,6 +630,35 @@ private:
/**@}*/
/**
+ * \defgroup hemedia
+ * @{
+ */
+
+ int loadres(HUGO_FILE infile, int reslen, int type);
+
+ int hugo_hasgraphics();
+
+ int hugo_displaypicture(HUGO_FILE infile, long reslen);
+
+ void initsound();
+
+ void initmusic();
+
+ int hugo_playmusic(HUGO_FILE infile, long reslen, char loop_flag);
+
+ void hugo_musicvolume(int vol);
+
+ void hugo_stopmusic();
+
+ int hugo_playsample(HUGO_FILE infile, long reslen, char loop_flag);
+
+ void hugo_samplevolume(int vol);
+
+ void hugo_stopsample();
+
+ /**@}*/
+
+ /**
* \defgroup heobject - Object/property/attribute management functions
* @{
*/
@@ -840,6 +880,41 @@ private:
/**@}*/
/**
+ * \defgroup heres
+ * @{
+ */
+
+ void DisplayPicture();
+
+ void PlayMusic();
+
+ void PlaySample();
+
+ void PlayVideo();
+
+ /**
+ * Assumes that filename/resname contain a resourcefile name and a resource name.
+ * If resname is "", filename contains the path of the resource on disk.
+ * Returns the length of the resource if if the named resource is found.
+ *
+ * If FindResource() returns non-zero, the file is hot, i.e., it is open and positioned
+ * to the start of the resource.
+ *
+ * Note that resourcefiles are expected to be in (if not the current directory) "object" or "games",
+ * and on-disk resources in (if not the given directory) "source" or "resource" (where these are the
+ * environment variables "HUGO_...", not actual on-disk directories).
+ */
+ long FindResource(char *filename, char *resname);
+
+ /**
+ * Processes resourcefile/filename (and resource, if applicable).
+ * Returns 0 if a valid 0 parameter is passed as in "music 0" or "sound 0".
+ */
+ int GetResourceParameters(char *filename, char *resname, int restype);
+
+ /**@}*/
+
+ /**
* \defgroup herun
* @{
*/
@@ -934,7 +1009,7 @@ private:
int SetCompound(int t);
- /**@}*/
+ /**@}*/
/**
* \defgroup Miscellaneous
@@ -944,6 +1019,10 @@ private:
int hugo_fseek(Common::SeekableReadStream *s, long int offset, int whence) {
return s->seek(offset, whence);
}
+ int hugo_fseek(strid_t s, long int offset, int whence) {
+ Common::SeekableReadStream *rs = *s;
+ return hugo_fseek(rs, offset, whence);
+ }
int hugo_fgetc(Common::SeekableReadStream *s) {
return s->readByte();
@@ -977,6 +1056,10 @@ private:
size_t hugo_fread(void *ptr, size_t size, size_t count, Common::SeekableReadStream *s) {
return s->read(ptr, size * count);
}
+ size_t hugo_fread(void *ptr, size_t size, size_t count, strid_t s) {
+ Common::SeekableReadStream *rs = *s;
+ return hugo_fread(ptr, size, count, rs);
+ }
int hugo_fprintf(Common::WriteStream *s, const char *fmt, ...) {
va_list va;
@@ -1017,6 +1100,10 @@ private:
long hugo_ftell(Common::SeekableReadStream *s) {
return s->pos();
}
+ long hugo_ftell(strid_t s) {
+ Common::SeekableReadStream *rs = *s;
+ return hugo_ftell(rs);
+ }
int hugo_fclose(strid_t f) {
delete f;
@@ -1113,15 +1200,6 @@ public:
* Save the game to the passed stream
*/
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
-
- // TODO: Stubs to be Properly implemented
- void hugo_stopsample() {}
- void hugo_stopmusic() {}
- int hugo_hasgraphics() { return 0; }
- void DisplayPicture() {}
- void PlayMusic() {}
- void PlaySample() {}
- void PlayVideo() {}
};
} // End of namespace Hugo
diff --git a/engines/glk/hugo/hugo_defines.h b/engines/glk/hugo/hugo_defines.h
index 02cfab1882..1fb6892fca 100644
--- a/engines/glk/hugo/hugo_defines.h
+++ b/engines/glk/hugo/hugo_defines.h
@@ -31,8 +31,12 @@ namespace Hugo {
#define HEVERSION 3
#define HEREVISION 3
#define HEINTERIM ".0"
+
#define GLK
#define DEBUGGER 1
+#define GRAPHICS_SUPPORTED
+#define SOUND_SUPPORTED
+#define SETTITLE_SUPPORTED
#define MAXOBJLIST 32
#define MAX_CONTEXT_COMMANDS 32
@@ -47,6 +51,8 @@ namespace Hugo {
#define MAXCALLS 99
#define MAXBREAKPOINTS 99
#define MAX_CODE_HISTORY 99
+#define MAX_RES_PATH 255
+#define MAXRES 1024
#define CHARWIDTH 1
#define HUGO_FILE strid_t
@@ -150,7 +156,11 @@ browsing.
#define TAIL_RECURSION_ROUTINE (-1)
#define TAIL_RECURSION_PROPERTY (-2)
+/* For system_status: */
#define STAT_UNAVAILABLE ((short)-1)
+#define STAT_NOFILE 101
+#define STAT_NORESOURCE 102
+#define STAT_LOADERROR 103
#define PRINTFATALERROR(a) error("%s", a)
@@ -163,6 +173,9 @@ browsing.
#define FORCE_REDRAW 1
+#define PIC 0
+#define SND 1
+
#endif
} // End of namespace Hugo
diff --git a/engines/glk/hugo/hugo_types.h b/engines/glk/hugo/hugo_types.h
index fcdaa8ed27..a6d9658258 100644
--- a/engines/glk/hugo/hugo_types.h
+++ b/engines/glk/hugo/hugo_types.h
@@ -90,6 +90,19 @@ enum ERROR_TYPE {
DIVIDE_E ///< divide by zero
};
+enum RESOURCE_TYPE {
+ JPEG_R, ///< JPEG image
+ WAVE_R, ///< RIFF WAVE audio sample
+ MOD_R, ///< MOD music module
+ S3M_R, ///< S3M music module
+ XM_R, ///< XM music module
+ MIDI_R, ///< MIDI music
+ MP3_R, ///< MP3 audio layer
+ AVI_R, ///< Video for Windows
+ MPEG_R, ///< MPEG video
+ UNKNOWN_R
+};
+
/**
* A structure used for disambiguation in MatchObject()
*/
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index fcb47149c1..d84d542825 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -74,9 +74,11 @@ MODULE_OBJS := \
hugo/detection.o \
hugo/heexpr.o \
hugo/heglk.o \
+ hugo/hemedia.o \
hugo/hemisc.o \
hugo/heobject.o \
hugo/heparse.o \
+ hugo/heres.o \
hugo/herun.o \
hugo/heset.o \
hugo/htokens.o \