From e3d34b67cb1a35a1670e0aa994a60bd0c3a8395d Mon Sep 17 00:00:00 2001 From: Jason Stevens Date: Sun, 25 Feb 2024 10:47:44 +0000 Subject: [PATCH] Added DosBeep --- Makefile | 185 ++--- Makefile.gnu | 35 + Makefile.os2 | 32 + cycle.c | 1 + dummy.c | 7 +- include/sarien.h | 10 +- nothing.c | 8 + nullvid.c | 98 ++- object | Bin 331 -> 0 bytes sarien.def | 16 +- sarien.lnk | 20 +- savegame.c | 1706 +++++++++++++++++++++++----------------------- sound.c | 225 +----- 13 files changed, 1144 insertions(+), 1199 deletions(-) create mode 100644 Makefile.gnu create mode 100644 Makefile.os2 create mode 100644 nothing.c delete mode 100644 object diff --git a/Makefile b/Makefile index 7ee8d16..7b1d35b 100644 --- a/Makefile +++ b/Makefile @@ -1,92 +1,93 @@ -# Version 6.00.054 1989 -# https://archive.org/details/os2ddk1.2 -# PLATFORM = ddk12 - -# Version 6.00.054 1989 -# https://archive.org/details/os2ddk2.0 -# PLATFORM = ddk20 - -# Version 6.00.054 1989 -# https://archive.org/details/os-2-cd-rom_202401 -# PLATFORM = ddksrc - -# Version 1.00.075 1989 -# https://archive.org/details/msos2-200-sdk -# PLATFORM = c386 - -# Version 6.00.077 1991 -# https://archive.org/details/windows-nt-3.1-build-196 -# PLATFORM = nt-sep - -# Version 6.00.080 1991 -# https://archive.org/details/windows-nt-3.1-october-1991-build -# PLATFORM = nt-oct - -# Version 6.00.081 1991 -# https://archive.org/details/Windows_NT_and_Win32_Dev_Kit_1991 -PLATFORM = nt-dec - -# Version 8.00 1993 -# PLATFORM = msvc32s - -# Version 8.00.3200 1993 -# Windows 95 73g SDk -# PLATFORM = 73g - -# Version 13.10.4035 2002 -# PLATFORM = v13 -# PLATFORM = 13.10.6030 - -DEFS = -D__32BIT__ -DM_I386 -D _MSC_VER=6 -DKEYS_WORK -INC = /u /w -Iinclude $(DEFS) -# OPT = /G3 /O -OPT = /G3 /Ogilt /Gs -DEBUG = #/Zi -LDEBUG = #-debug:full - -# OS/2 compat dos extender (pharlap286) -DOSX = run286 - -# ms-dos emulator -EMU = msdos486 - -# dos exteded cross -CC = $(EMU) $(DOSX) $(CL386ROOT)\$(PLATFORM)\cl386 -# native CC -#CC = $(CL386ROOT)\$(PLATFORM)\cl386 - -OS2LINK = $(EMU) $(DOSX) $(CL386ROOT)\ddk12\LINK386.EXE - - - -OBJ = agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj \ - font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj \ -keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj op_cmd.obj \ -op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj savegame.obj \ -silent.obj sound.obj sprite.obj text.obj view.obj words.obj fileglob.obj - -INVOLVED = fileglob.obj - -HARD = dummy.obj pccga.obj pcvga.obj pharcga.obj pharvid.obj - -NULL = dummy.obj nullvid.obj - - -# must include ONLY ONE strategey.. -# for OS/2 it must have been assembled my MASM 6.11 - -include ..\-justcompile.mak -#include ..\-mangleassembly.mak -#include ..\-plainassembly.mak - -sarien: $(OBJ) $(NULL) - $(OS2LINK) @sarien.lnk - mcopy -i %QEMUPATH%\dummy.vfd -D o sarien.exe :: - qemuos2 - - -clean: - del $(OBJ) - del sarien.exe - del *.asm *.a1 *.a - +# Version 6.00.054 1989 +# https://archive.org/details/os2ddk1.2 +# PLATFORM = ddk12 + +# Version 6.00.054 1989 +# https://archive.org/details/os2ddk2.0 +# PLATFORM = ddk20 + +# Version 6.00.054 1989 +# https://archive.org/details/os-2-cd-rom_202401 +# PLATFORM = ddksrc + +# Version 1.00.075 1989 +# https://archive.org/details/msos2-200-sdk +# PLATFORM = c386 + +# Version 6.00.077 1991 +# https://archive.org/details/windows-nt-3.1-build-196 +# PLATFORM = nt-sep + +# Version 6.00.080 1991 +# https://archive.org/details/windows-nt-3.1-october-1991-build +# PLATFORM = nt-oct + +# Version 6.00.081 1991 +# https://archive.org/details/Windows_NT_and_Win32_Dev_Kit_1991 +PLATFORM = nt-dec + +# Version 8.00 1993 +# PLATFORM = msvc32s + +# Version 8.00.3200 1993 +# Windows 95 73g SDk +# PLATFORM = 73g + +# Version 13.10.4035 2002 +# PLATFORM = v13 +# PLATFORM = 13.10.6030 + +DEFS = -D__32BIT__ -DM_I386 -D _MSC_VER=6 -DKEYS_WORK +INC = /u /w -Iinclude $(DEFS) +# OPT = /G3 /O +OPT = /G3 /Ogilt /Gs +DEBUG = #/Zi +LDEBUG = #-debug:full + +# OS/2 compat dos extender (pharlap286) +DOSX = run286 + +# ms-dos emulator +EMU = msdos486 + +# dos exteded cross +CC = $(EMU) $(DOSX) $(CL386ROOT)\$(PLATFORM)\cl386 +# native CC +#CC = $(CL386ROOT)\$(PLATFORM)\cl386 + +OS2LINK = $(EMU) $(DOSX) $(CL386ROOT)\ddk12\LINK386.EXE + + + +OBJ = agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj \ + font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj \ +keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj op_cmd.obj \ +op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj savegame.obj \ +silent.obj sound.obj sprite.obj text.obj view.obj words.obj fileglob.obj nothing.obj + +INVOLVED = fileglob.obj + +HARD = dummy.obj pccga.obj pcvga.obj pharcga.obj pharvid.obj + +NULL = dummy.obj nullvid.obj + + +# must include ONLY ONE strategey.. +# for OS/2 it must have been assembled my MASM 6.11 + +include ..\-justcompile.mak +#include ..\-mangleassembly.mak +#include ..\-plainassembly.mak + +sarien: $(OBJ) $(NULL) + SET LIB=C:\cl386-research\lib2 + $(OS2LINK) @sarien.lnk + mcopy -i %QEMUPATH%\dummy.vfd -D o sarien.exe :: + qemuos2 + + +clean: + del $(OBJ) $(NULL) + del sarien.exe + del *.asm *.a1 *.a + diff --git a/Makefile.gnu b/Makefile.gnu new file mode 100644 index 0000000..4dc3556 --- /dev/null +++ b/Makefile.gnu @@ -0,0 +1,35 @@ + +DEFS = -D__32BIT__ -DM_I386 -D _MSC_VER=6 -DKEYS_WORK -DNEED_NOTHING +INC = -Iinclude +#OPT = /G3 /O +#OPT = /G3 /Ogilt /Gs +DEBUG = #/Zi +LDEBUG = #-debug:full +CC=gcc +OS2LINK = LINK386.EXE + +CFLAGS= $(INC) $(DEFS) $(OPT) + +OBJ = agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj \ + font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj \ +keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj op_cmd.obj \ +op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj savegame.obj \ +silent.obj sound.obj sprite.obj text.obj view.obj words.obj nothing.obj + +sarien: $(OBJ) + +# gnu make (cross compiled) +%.obj: %.c + $(CC) $(CFLAGS) -c $*.c + o2obj $*.o + rm $*.o +# nmake +#.c.obj: +# @emxomf -o $*.obj $*.o +# @del $*.o + + +clean: + del $(OBJ) + del sarien.exe + del *.asm *.a1 *.a diff --git a/Makefile.os2 b/Makefile.os2 new file mode 100644 index 0000000..73c8c50 --- /dev/null +++ b/Makefile.os2 @@ -0,0 +1,32 @@ + +DEFS = -D__32BIT__ -DM_I386 -D _MSC_VER=6 -DKEYS_WORK +INC = /u /w -Iinclude +OPT = /G3 /Ox +#OPT = /G3 /Ogilt /Gs +DEBUG = #/Zi +LDEBUG = #-debug:full +CC=cl386 +OS2LINK = LINK386.EXE + +CFLAGS= $(INC) $(DEFS) $(OPT) + +OBJ = agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj \ + font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj \ +keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj op_cmd.obj \ +op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj savegame.obj \ +silent.obj sound.obj sprite.obj text.obj view.obj words.obj fileglob.obj +INVOLVED = fileglob.obj +HARD = dummy.obj pccga.obj pcvga.obj pharcga.obj pharvid.obj +NULL = dummy.obj nullvid.obj + +sarien: $(OBJ) $(NULL) + $(OS2LINK) @sarien.lnk + +.c.obj: + $(CC) $(CFLAGS) /c $*.c + + +clean: + @del $(OBJ) + @del sarien.exe + @del *.asm *.a1 *.a diff --git a/cycle.c b/cycle.c index 64b62da..458e399 100644 --- a/cycle.c +++ b/cycle.c @@ -151,6 +151,7 @@ static void interpret_cycle () void update_timer () { clock_count++; +play_sound(); if (clock_count <= TICK_SECONDS) return; diff --git a/dummy.c b/dummy.c index fd10af6..9310bf4 100644 --- a/dummy.c +++ b/dummy.c @@ -30,15 +30,10 @@ void __init_sound () static int dummy2_init_sound (SINT16 *buffer) { report ("sound_dummy: sound output disabled\n"); - return -1; + return 0; } static void dummy2_close_sound () { } -void nosound(){} -void sound(){} - - - diff --git a/include/sarien.h b/include/sarien.h index 7265f4d..0b192eb 100644 --- a/include/sarien.h +++ b/include/sarien.h @@ -65,6 +65,7 @@ extern "C"{ //#define _TRACE +#if 0 /* You'll need an ANSI terminal to use these :\ */ #ifdef _TRACE # include @@ -90,16 +91,21 @@ extern "C"{ # undef _D # endif # if defined(__GNUC__) /* && !defined(MACOSX) */ -# define _D(args...) +//# define _D(args...) # else - void _D(char *, ...); +// void _D(char *, ...); # endif #endif /* _TRACE */ //yuck # define _D_INFO # define _D_CRIT # define _D_WARN +#endif +#define _D_INFO +#define _D_CRIT +#define _D_WARN +#define _D nothing /* Include port-specific definitions * diff --git a/nothing.c b/nothing.c new file mode 100644 index 0000000..e106b41 --- /dev/null +++ b/nothing.c @@ -0,0 +1,8 @@ +//GCC doesnt seem to do this correctly?! + +#ifdef NEED_NOTHING +void nothing(){} +#endif + + + diff --git a/nullvid.c b/nullvid.c index 3b8a59d..4491a6e 100644 --- a/nullvid.c +++ b/nullvid.c @@ -15,6 +15,8 @@ #define INCL_WINDIALOGS #define INCL_GPIPRIMITIVES #define INCL_DOSPROCESS +#define INCL_DOSQUEUES +#define INCL_DOSERRORS #include #include @@ -33,6 +35,7 @@ HPS hps, hpsMemory; HMTX hmtxLock; TID tidMain; TID tidTimer; +TID tidBeeper; #define STACK 8192 /* Stack size for thread */ @@ -103,6 +106,9 @@ static int draw_frame_skip; #define KEY_ENTER 0x0D +PSZ szQueueName = "\\QUEUES\\SARIEN.QUE"; +HQUEUE hqSpecialQue = 0; +#define QUE_CONVERT_ADDRESS 0x00000004 ////////////////////////////////////////////////////////////// #include "sarien.h" @@ -135,6 +141,65 @@ static struct gfx_driver gfx_pcvga = { pc_get_key }; +typedef struct { + int freq; + int duration; + }QueueBeep; + + +void Beeper(){ + +PID pidOwner=0; +REQUESTDATA Request = {0}; +//PSZ DataBuffer = ""; +int* DataBuffer; +BYTE ElemPrty = 0; +ULONG ulDataLen = 0; +int rc; +QueueBeep mybeep; + +rc=DosOpenQueue(&pidOwner,&hqSpecialQue,szQueueName); +if(rc!=NO_ERROR) { + printf("Error with thread openeing Queue %s\n",szQueueName); + exit(-1); + } +for(;;) { + rc=DosReadQueue(hqSpecialQue, + &Request, + &ulDataLen, + (PVOID) &DataBuffer, + 0L, + DCWW_WAIT, + &ElemPrty, + 0L); + if(rc!=ERROR_QUE_EMPTY) { + + mybeep.freq=(int)DataBuffer; + *DataBuffer++; + mybeep.duration=(int)DataBuffer; //9 100 + DosBeep(mybeep.freq/7,mybeep.duration/100); + } +// DosSleep(32L); + } +} + +void SendBeep(int freq,int duration) { +QueueBeep mybeep; +mybeep.freq=freq; +mybeep.duration=duration; + +DosWriteQueue (hqSpecialQue, + 12345L, + sizeof(freq), + freq, + 0L); +DosWriteQueue (hqSpecialQue, + 12345L, + sizeof(duration), + duration, + 0L); +} + void Timer(){ for(;;) { DosSleep(20L); @@ -148,7 +213,7 @@ static void pc_timer () while (cticks == clock_ticks){DosSleep(5);} cticks = clock_ticks; - draw_frame++; + //draw_frame++; } @@ -204,6 +269,11 @@ static void pc_put_block (int x1, int y1, int x2, int y2) Bitmap[((NUM_MASSES_Y-y)*(GFX_WIDTH))-(GFX_WIDTH-x)] = RGBmap[disp_val]; } } + // skip frame happens here + // for some reason it constantly stalls. + // have to keep hitting enter :( + // if(draw_frame>draw_frame_skip) { + DosRequestMutexSem(hmtxLock, SEM_INDEFINITE_WAIT); /* This is the key to the speed. Instead of doing a GPI call to set the @@ -249,6 +319,7 @@ int main(int argc, char *argv[]) QMSG qmsg; ULONG flFlags; unsigned char class[]="MyClass"; + int rc; flFlags = FCF_TITLEBAR | FCF_MINBUTTON | @@ -292,16 +363,28 @@ int main(int argc, char *argv[]) /* Create a semaphore to control access to the memory image presentation space. Only one thread can perform Gpi operations on it at a time. */ - DosCreateMutexSem("\\sem32\\Lock", &hmtxLock, 0, FALSE); + rc=DosCreateMutexSem("\\sem32\\Lock", &hmtxLock, 0, FALSE); + if(rc!=NO_ERROR) { + printf("DosCreateMutexSem \\sem32\\Lock returned error\n"); + exit (-1); + } + + DosCreateQueue(&hqSpecialQue,QUE_FIFO,szQueueName); + if(rc!=NO_ERROR) { + printf("DosCreateQueue %s returned error\n",szQueueName); + exit (-1); + } /* Create a thread to run the system model. */ DosCreateThread(&tidMain,OLDmain, 0UL, 0UL, STACK); DosCreateThread(&tidTimer,Timer, 0UL, 0UL, STACK); + DosCreateThread(&tidBeeper,Beeper, 0UL, 0UL, STACK); - draw_frame=1000; - draw_frame_skip=60; +/* draw_frame=1000; + draw_frame_skip=2; if(argc>1) - draw_frame_skip=atoi(argv[1]); + draw_frame_skip=atoi(argv[1]); */ + while (WinGetMsg(hab, &qmsg, (HWND) NULL, 0, 0)) { WinDispatchMsg(hab, &qmsg); @@ -403,14 +486,12 @@ window_func(HWND handle, ULONG mess, MPARAM parm1, MPARAM parm2) case WM_ERASEBACKGROUND: case WM_PAINT: /* Copy the memory image of the screen out to the real screen. */ - if(draw_frame>draw_frame_skip) { + //This gets called when you move the window, or something pops up DosRequestMutexSem(hmtxLock, SEM_INDEFINITE_WAIT); WinBeginPaint(handle, hps, NULL); GpiBitBlt(hps, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_AND); WinEndPaint(hps); DosReleaseMutexSem(hmtxLock); - draw_frame=1; - } break; case WM_CHAR: @@ -502,5 +583,4 @@ PrepareGraphics(BYTE *RGBmap) } } - \ No newline at end of file diff --git a/object b/object deleted file mode 100644 index 8ae7654c59da23e642af886fb87a426db3cf3062..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331 zcmaLQOHRT-0D$4PX{QLarR6bFX&nR-e4#}HAu-^XHcH|OMBPq89A`6-PTHMUVCOMh zxOC46ynu=4U?E<>{g?mmr>{8_ZpXC3vB|_!m}Ds_p7)BV|hzE(D#=@#BlwijwPRGQLV5#Jp?65^l9sRfs@S zG6lDxvLNc}yNbgd0OTm__?fbPYL70Wg9K&l9InakoC9#9Hgfo55<@;Tbn xk!$4dXEg~}-U;-o<8T0d#X5IbeLApwg&Z9NFDpUKE2-Qx^Tp_JIs}e}e*rC%O7j2! diff --git a/sarien.def b/sarien.def index 5e66dc4..ff64243 100644 --- a/sarien.def +++ b/sarien.def @@ -1,8 +1,8 @@ -;----------------------------------- -; BEZIER.DEF module definition file -;----------------------------------- - -NAME FASTGPI WINDOWAPI - -DESCRIPTION 'Sarien 0.8.0-j2me' -STACKSIZE 256000 +;----------------------------------- +; BEZIER.DEF module definition file +;----------------------------------- + +NAME FASTGPI WINDOWAPI + +DESCRIPTION 'Sarien 0.8.0-j2me' +STACKSIZE 256000 diff --git a/sarien.lnk b/sarien.lnk index b175124..3a628df 100644 --- a/sarien.lnk +++ b/sarien.lnk @@ -1,11 +1,11 @@ -agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj + -font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj + -keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj fileglob.obj + -op_cmd.obj op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj + -savegame.obj silent.obj sound.obj sprite.obj text.obj view.obj words.obj + -dummy.obj nullvid.obj -sarien /NOE /NOI /NOD:OLDNAMES /STACK:256000 -nul.map -..\..\lib2\libc.lib + -..\..\lib2\os2386.lib +agi.obj agi_v2.obj agi_v3.obj agi_v4.obj checks.obj cli.obj console.obj cycle.obj + +font.obj getopt.obj getopt1.obj global.obj graphics.obj hirespic.obj id.obj inv.obj + +keyboard.obj logic.obj lzw.obj main.obj menu.obj motion.obj objects.obj fileglob.obj + +op_cmd.obj op_dbg.obj op_test.obj patches.obj path.obj picture.obj picview.obj rand.obj + +savegame.obj silent.obj sound.obj sprite.obj text.obj view.obj words.obj + +dummy.obj nullvid.obj nothing.obj +sarien /NOE /NOI /NOD:OLDNAMES /NOD:LIBCRT /NOD:LIBGCC /STACK:384000 +nul.map +libc.lib + +os2386.lib sarien.def; \ No newline at end of file diff --git a/savegame.c b/savegame.c index 2ff85eb..e6e9583 100644 --- a/savegame.c +++ b/savegame.c @@ -1,853 +1,853 @@ -/* Sarien - A Sierra AGI resource interpreter engine - * Copyright (C) 1999-2003 Stuart George and Claudio Matsuoka - * - * $Id: savegame.c,v 1.82 2003/08/07 06:41:24 cmatsuoka Exp $ - * - * 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; see docs/COPYING for further details. - */ - -/* - * Savegame support by Vasyl Tsvirkunov - * Multi-slots by Claudio Matsuoka - */ - -#include -#include - -#if !defined(DREAMCAST) && !defined(CIBYL) && !defined(__MPW__) && !defined(PALMOS) -# ifndef __DICE__ -# include -# include -# endif -#endif - -#ifdef WIN32 -# include -#endif - -#include "sarien.h" -#include "agi.h" -#include "graphics.h" -#include "sprite.h" -#include "text.h" -#include "savegame.h" -#include "keyboard.h" -#include "menu.h" - -#undef fopen - -#if defined(__DICE__) || defined(WIN32) -# define MKDIR(a,b) mkdir(a) -#elif defined(CIBYL) -# define MKDIR(a,b) -#else -# define MKDIR(a,b) mkdir(a,b) -#endif - -/* Image stack support */ -struct image_stack_element { - UINT8 type; - UINT8 pad; - SINT16 parm1; - SINT16 parm2; - SINT16 parm3; - SINT16 parm4; - SINT16 parm5; - SINT16 parm6; - SINT16 parm7; -}; - -#define INITIAL_IMAGE_STACK_SIZE 32 -static int stack_size = 0; -static struct image_stack_element* image_stack = NULL; -static int image_stack_pointer = 0; - -void clear_image_stack(void) -{ - image_stack_pointer = 0; -} - -void release_image_stack(void) -{ - if(image_stack) - free(image_stack); - image_stack = NULL; - stack_size = image_stack_pointer = 0; -} - -void record_image_stack_call(UINT8 type, SINT16 p1, SINT16 p2, SINT16 p3, - SINT16 p4, SINT16 p5, SINT16 p6, SINT16 p7) -{ - struct image_stack_element* pnew; - - if (image_stack_pointer == stack_size) { - if (stack_size == 0) { /* first call */ - image_stack = (struct image_stack_element *)malloc(INITIAL_IMAGE_STACK_SIZE*sizeof(struct image_stack_element)); - stack_size = INITIAL_IMAGE_STACK_SIZE; - } else { /* has to grow */ - struct image_stack_element* new_stack; - new_stack = (struct image_stack_element *)malloc(2*stack_size*sizeof(struct image_stack_element)); - memcpy(new_stack, image_stack, stack_size*sizeof(struct image_stack_element)); - free(image_stack); - image_stack = new_stack; - stack_size *= 2; - } - } - - pnew = &image_stack[image_stack_pointer]; - image_stack_pointer++; - - pnew->type = type; - pnew->parm1 = p1; - pnew->parm2 = p2; - pnew->parm3 = p3; - pnew->parm4 = p4; - pnew->parm5 = p5; - pnew->parm6 = p6; - pnew->parm7 = p7; -} - -void replay_image_stack_call(UINT8 type, SINT16 p1, SINT16 p2, SINT16 p3, - SINT16 p4, SINT16 p5, SINT16 p6, SINT16 p7) -{ - switch(type) { - case ADD_PIC: - _D (_D_WARN "--- decoding picture %d ---", p1); - agi_load_resource (rPICTURE, p1); - decode_picture (p1, p2); - break; - case ADD_VIEW: - agi_load_resource (rVIEW, p1); - add_to_pic (p1, p2, p3, p4, p5, p6, p7); - break; - } -} - -/* */ - -static char* strSig = "Sarien:"; - -#ifndef PALMOS - -static void write_uint8(FILE* f, SINT8 val) -{ - fwrite(&val, 1, 1, f); -} - -static void write_sint16(FILE* f, SINT16 val) -{ - static UINT8 buf[2]; - buf[0] = (UINT8)((val>>8)&255); - buf[1] = (UINT8)(val&255); - fwrite(buf, 1, 2, f); -} - -static void write_uint16(FILE* f, UINT16 val) -{ - static UINT8 buf[2]; - buf[0] = (UINT8)((val>>8)&255); - buf[1] = (UINT8)(val&255); - fwrite(buf, 1, 2, f); -} - -static UINT8 read_uint8(FILE* f) -{ - static UINT8 buf[1]; - fread(buf, 1, 1, f); - return buf[0]; -} - -static UINT16 read_uint16(FILE* f) -{ - static UINT8 buf[2]; - fread(buf, 1, 2, f); - return (buf[0]<<8)|buf[1]; -} - -static SINT16 read_sint16(FILE* f) -{ - static UINT8 buf[2]; - fread(buf, 1, 2, f); - return (SINT16)((buf[0]<<8)|buf[1]); -} - - -static void write_string (FILE* f, char* s) -{ - write_sint16 (f, (SINT16)strlen(s)); - fwrite(s, 1, strlen(s), f); -} - -static void read_string (FILE* f, char* s) -{ - SINT16 size = read_sint16(f); - fread (s, 1, size, f); - s[size] = (char)0; -} - -static void write_bytes (FILE* f, char* s, SINT16 size) -{ - fwrite (s, 1, size, f); -} - -static void read_bytes (FILE* f, char* s, SINT16 size) -{ - fread (s, 1, size, f); -} - - -/* - * Version 0: view table has 64 entries - * Version 1: view table has 256 entries (needed in KQ3) - */ -#define SAVEGAME_VERSION 1 - -int save_game (char* s, char* d) -{ - SINT16 i; - struct image_stack_element* ptr = image_stack; - FILE* f = fopen (s, "wb"); - - if(!f) - return err_BadFileOpen; - - write_bytes (f, strSig, 8); - write_string (f, d); - - write_uint8 (f, (UINT8)SAVEGAME_VERSION); - write_uint8 (f, (UINT8)game.state); - /* game.name */ - write_string (f, game.id); - /* game.crc */ - - for (i = 0; i < MAX_FLAGS; i++) - write_uint8 (f, game.flags[i]); - for (i = 0; i < MAX_VARS; i++) - write_uint8 (f, game.vars[i]); - - write_sint16 (f, (SINT8)game.horizon); - write_sint16 (f, (SINT16)game.line_status); - write_sint16 (f, (SINT16)game.line_user_input); - write_sint16 (f, (SINT16)game.line_min_print); - /* game.cursor_pos */ - /* game.input_buffer */ - /* game.echo_buffer */ - /* game.keypress */ - write_sint16 (f, (SINT16)game.input_mode); - write_sint16 (f, (SINT16)game.lognum); - - write_sint16 (f, (SINT16)game.player_control); - write_sint16 (f, (SINT16)game.quit_prog_now); - write_sint16 (f, (SINT16)game.status_line); - write_sint16 (f, (SINT16)game.clock_enabled); - write_sint16 (f, (SINT16)game.exit_all_logics); - write_sint16 (f, (SINT16)game.picture_shown); - write_sint16 (f, (SINT16)game.has_prompt); - write_sint16 (f, (SINT16)game.game_flags); - - /* Reversed to keep compatibility with old savegames */ - write_sint16 (f, (SINT16)!game.input_enabled); - - for (i = 0; i < _HEIGHT; i++) - write_uint8 (f, game.pri_table[i]); - - /* game.msg_box_ticks */ - /* game.block */ - /* game.window */ - /* game.has_window */ - - write_sint16 (f, (SINT16)game.gfx_mode); - write_uint8 (f, game.cursor_char); - write_sint16 (f, (SINT16)game.color_fg); - write_sint16 (f, (SINT16)game.color_bg); - - /* game.hires (#ifdef USE_HIRES) */ - /* game.sbuf */ - /* game.ego_words */ - /* game.num_ego_words */ - - write_sint16 (f, (SINT16)game.num_objects); - for (i = 0; i < (SINT16)game.num_objects; i++) - write_sint16 (f, (SINT16)object_get_location(i)); - - /* game.ev_keyp */ - for (i = 0; i < MAX_STRINGS; i++) - write_string (f, game.strings[i]); - - /* record info about loaded resources */ - for (i = 0; i < MAX_DIRS; i++) { - write_uint8 (f, game.dir_logic[i].flags); - write_sint16 (f, (SINT16)game.logics[i].sIP); - write_sint16 (f, (SINT16)game.logics[i].cIP); - } - for (i = 0; i < MAX_DIRS; i++) - write_uint8(f, game.dir_pic[i].flags); - for (i = 0; i < MAX_DIRS; i++) - write_uint8(f, game.dir_view[i].flags); - for (i = 0; i < MAX_DIRS; i++) - write_uint8(f, game.dir_sound[i].flags); - - /* game.pictures */ - /* game.logics */ - /* game.views */ - /* game.sounds */ - - for(i = 0; i < MAX_VIEWTABLE; i++) { - struct vt_entry* v = &game.view_table[i]; - - write_uint8(f, v->step_time); - write_uint8(f, v->step_time_count); - write_uint8(f, v->entry); - write_sint16(f, v->x_pos); - write_sint16(f, v->y_pos); - write_uint8(f, v->current_view); - - /* v->view_data */ - - write_uint8(f, v->current_loop); - write_uint8(f, v->num_loops); - - /* v->loop_data */ - - write_uint8(f, v->current_cel); - write_uint8(f, v->num_cels); - - /* v->cel_data */ - /* v->cel_data_2 */ - - write_sint16(f, v->x_pos2); - write_sint16(f, v->y_pos2); - - /* v->s */ - - write_sint16(f, v->x_size); - write_sint16(f, v->y_size); - write_uint8(f, v->step_size); - write_uint8(f, v->cycle_time); - write_uint8(f, v->cycle_time_count); - write_uint8(f, v->direction); - - write_uint8(f, v->motion); - write_uint8(f, v->cycle); - write_uint8(f, v->priority); - - write_uint16(f, v->flags); - - write_uint8(f, v->parm1); - write_uint8(f, v->parm2); - write_uint8(f, v->parm3); - write_uint8(f, v->parm4); - } - - /* Save image stack */ - - for (i = 0; i < image_stack_pointer; i++) { - ptr = &image_stack[i]; - write_uint8 (f, ptr->type); - write_sint16 (f, ptr->parm1); - write_sint16 (f, ptr->parm2); - write_sint16 (f, ptr->parm3); - write_sint16 (f, ptr->parm4); - write_sint16 (f, ptr->parm5); - write_sint16 (f, ptr->parm6); - write_sint16 (f, ptr->parm7); - } - write_uint8(f, 0); - - fclose(f); - - return err_OK; -} - -int load_game(char* s) -{ - int i, ver, vt_entries = MAX_VIEWTABLE; - UINT8 t; - SINT16 parm[7]; - char sig[8]; - char id[8]; - char description[256]; - FILE *f = fopen(s, "rb"); - - if(!f) - return err_BadFileOpen; - - read_bytes(f, sig, 8); - if (strncmp (sig, strSig, 8)) { - fclose(f); - return err_BadFileOpen; - } - - read_string (f, description); - - ver = read_uint8(f); - if (ver == 0) - vt_entries = 64; - game.state = read_uint8(f); - /* game.name - not saved */ - read_string(f, id); - if(strcmp(id, game.id)) { - fclose(f); - return err_BadFileOpen; - } - /* game.crc - not saved */ - - for (i = 0; i < MAX_FLAGS; i++) - game.flags[i] = read_uint8(f); - for (i = 0; i < MAX_VARS; i++) - game.vars[i] = read_uint8(f); - - game.horizon = read_sint16(f); - game.line_status = read_sint16(f); - game.line_user_input = read_sint16(f); - game.line_min_print = read_sint16(f); - - /* These are never saved */ - game.cursor_pos = 0; - game.input_buffer[0] = 0; - game.echo_buffer[0] = 0; - game.keypress = 0; - - game.input_mode = read_sint16(f); - game.lognum = read_sint16(f); - - game.player_control = read_sint16(f); - game.quit_prog_now = read_sint16(f); - game.status_line = read_sint16(f); - game.clock_enabled = read_sint16(f); - game.exit_all_logics = read_sint16(f); - game.picture_shown = read_sint16(f); - game.has_prompt = read_sint16(f); - game.game_flags = read_sint16(f); - game.input_enabled = !read_sint16(f); - - for (i = 0; i < _HEIGHT; i++) - game.pri_table[i] = read_uint8(f); - - if(game.has_window) - close_window(); - game.msg_box_ticks = 0; - game.block.active = FALSE; - /* game.window - fixed by close_window() */ - /* game.has_window - fixed by close_window() */ - - game.gfx_mode = read_sint16(f); - game.cursor_char = read_uint8(f); - game.color_fg = read_sint16(f); - game.color_bg = read_sint16(f); - - /* game.hires (#ifdef USE_HIRES) - rebuilt from image stack */ - /* game.sbuf - rebuilt from image stack */ - - /* game.ego_words - fixed by clean_input */ - /* game.num_ego_words - fixed by clean_input */ - - game.num_objects = read_sint16(f); - for(i = 0; i < (SINT16)game.num_objects; i++) - object_set_location(i, read_sint16(f)); - - /* Those are not serialized */ - for (i = 0; i < MAX_DIRS; i++) { - game.ev_keyp[i].occured = FALSE; - } - - for (i = 0; i < MAX_STRINGS; i++) - read_string (f, game.strings[i]); - - for (i = 0; i < MAX_DIRS; i++) { - if(read_uint8(f) & RES_LOADED) - agi_load_resource (rLOGIC, i); - else - agi_unload_resource (rLOGIC, i); - game.logics[i].sIP = read_sint16(f); - game.logics[i].cIP = read_sint16(f); - } - - for (i = 0; i < MAX_DIRS; i++) { - if(read_uint8(f) & RES_LOADED) - agi_load_resource(rPICTURE, i); - else - agi_unload_resource(rPICTURE, i); - } - - for (i = 0; i < MAX_DIRS; i++) { - if(read_uint8(f) & RES_LOADED) - agi_load_resource(rVIEW, i); - else - agi_unload_resource(rVIEW, i); - } - - for(i = 0; i < MAX_DIRS; i++) { - if(read_uint8(f) & RES_LOADED) - agi_load_resource(rSOUND, i); - else - agi_unload_resource(rSOUND, i); - } - - /* game.pictures - loaded above */ - /* game.logics - loaded above */ - /* game.views - loaded above */ - /* game.sounds - loaded above */ - - for (i = 0; i < vt_entries; i++) { - struct vt_entry* v = &game.view_table[i]; - - v->step_time = read_uint8(f); - v->step_time_count = read_uint8(f); - v->entry = read_uint8(f); - v->x_pos = read_sint16(f); - v->y_pos = read_sint16(f); - v->current_view = read_uint8(f); - - /* v->view_data - fixed below */ - - v->current_loop = read_uint8(f); - v->num_loops = read_uint8(f); - - /* v->loop_data - fixed below */ - - v->current_cel = read_uint8(f); - v->num_cels = read_uint8(f); - - /* v->cel_data - fixed below */ - /* v->cel_data_2 - fixed below */ - - v->x_pos2 = read_sint16(f); - v->y_pos2 = read_sint16(f); - - /* v->s - fixed below */ - - v->x_size = read_sint16(f); - v->y_size = read_sint16(f); - v->step_size = read_uint8(f); - v->cycle_time = read_uint8(f); - v->cycle_time_count = read_uint8(f); - v->direction = read_uint8(f); - - v->motion = read_uint8(f); - v->cycle = read_uint8(f); - v->priority = read_uint8(f); - - v->flags = read_uint16(f); - - v->parm1 = read_uint8(f); - v->parm2 = read_uint8(f); - v->parm3 = read_uint8(f); - v->parm4 = read_uint8(f); - } - for (i = vt_entries; i < MAX_VIEWTABLE; i++) { - memset (&game.view_table[i], 0, sizeof (struct vt_entry)); - } - - /* Fix some pointers in viewtable */ - - for (i = 0; i < MAX_VIEWTABLE; i++) { - struct vt_entry* v = &game.view_table[i]; - - if(game.dir_view[v->current_view].offset == _EMPTY) - continue; - - if(!(game.dir_view[v->current_view].flags & RES_LOADED)) - agi_load_resource(rVIEW, v->current_view); - - set_view(v, v->current_view); /* Fix v->view_data */ - set_loop(v, v->current_loop); /* Fix v->loop_data */ - set_cel(v, v->current_cel); /* Fix v->cel_data */ - v->cel_data_2 = v->cel_data; - v->s = NULL; /* not sure if it is used... */ - } - - erase_both(); - - /* Clear input line */ - clear_screen(0); - write_status(); - - /* Recreate background from saved image stack */ - clear_image_stack(); - while ((t = read_uint8(f)) != 0) { - for (i = 0; i < 7; i++) - parm[i] = read_sint16(f); - replay_image_stack_call (t, parm[0], parm[1], parm[2], - parm[3], parm[4], parm[5], parm[6]); - } - - fclose(f); - - setflag(F_restore_just_ran, TRUE); - - game.has_prompt = 0; /* force input line repaint if necessary*/ - clean_input(); - - erase_both(); - blit_both(); - commit_both(); - show_pic(); - do_update(); - - return err_OK; -} -#endif /* PALMOS */ - -#define NUM_SLOTS 12 - -static int select_slot (char *path) -{ - int i, key, active = 0; - int rc = -1; - int hm = 2, vm = 3; /* box margins */ - char desc[NUM_SLOTS][40]; - - for (i = 0; i < NUM_SLOTS; i++) { - char name[MAX_PATH]; - FILE *f; - char sig[8]; - //sprintf (name, "%s/%08d.sav", path, i); - sprintf (name, "%08d.sav", i); - //printf("Opening %s\n", name); - f = fopen (name, "rb"); - if (f == NULL) { - strcpy (desc[i], " (empty slot)"); - } else { - read_bytes (f, sig, 8); - if (strncmp (sig, strSig, 8)) { - strcpy (desc[i], "(corrupt file)"); - } else { - read_string (f, desc[i]); - } - fclose(f); - } - } - - while (42) { - char dstr[64]; - for (i = 0; i < NUM_SLOTS; i++) { - sprintf (dstr, "[%-32.32s]", desc[i]); - print_text (dstr, 0, hm + 1, vm + 4 + i, - (40 - 2 * hm) - 1, - i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT, - i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR); - - } - - poll_timer (); /* msdos driver -> does nothing */ - key = do_poll_keyboard (); - if (!console_keyhandler (key)) { - switch (key) { - case KEY_ENTER: - rc = active; - strncpy (game.strings[MAX_STRINGS], - desc[i], MAX_STRINGLEN); - goto press; - case KEY_ESCAPE: - rc = -1; - goto getout; -#ifdef USE_MOUSE - case BUTTON_LEFT: - break; -#endif - case KEY_DOWN: - active++; - active %= NUM_SLOTS; - break; - case KEY_UP: - active--; - if (active < 0) - active = NUM_SLOTS - 1; - break; - } - } - console_cycle (); - } - -press: - _D (_D_WARN "Button pressed: %d", rc); - -getout: - close_window(); - return rc; -} - -int savegame_simple () -{ - char home[MAX_PATH], path[MAX_PATH]; - sprintf(path,"%08d.sav",game.id); - save_game (path, "save"); - - return err_OK; -} - - -int savegame_dialog () -{ - char home[MAX_PATH], path[MAX_PATH]; - char *desc; - char *buttons[] = { "Do as I say!", "I regret", NULL }; - char dstr[200]; - int rc, slot = 0; - int hm, vm, hp, vp; /* box margins */ - int w; - - hm = 2; vm = 3; - hp = hm * CHAR_COLS; vp = vm * CHAR_LINES; - w = (40 - 2 * hm) - 1; - -#if 0 - if (get_app_dir (home, MAX_PATH) < 0) { - message_box ("Couldn't save game."); - return err_BadFileOpen; - } - - /* DATADIR conflicts with ObjIdl.h in win32 SDK, renamed to DATA_DIR */ - sprintf (path, "%s/" DATA_DIR "/", home); - MKDIR (path, 0755); - sprintf (path, "%s/" DATA_DIR "/%05X.%s/", home, game.crc, game.id); - MKDIR (path, 0711); - -#endif - - erase_both (); - - draw_window (hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); - print_text ("Select a slot in which you wish to save the game:", - 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - print_text ("Press ENTER to select, ESC cancels", - 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - - slot = select_slot (path); - if (slot < 0) /* ESC pressed */ - return err_OK; - - /* Get savegame description */ - draw_window (hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp, - GFX_HEIGHT - vp - 9 * CHAR_LINES); - print_text ("Enter a description for this game:", - 0, hm + 1, vm + 6, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - draw_rectangle (3 * CHAR_COLS, 11 * CHAR_LINES - 1, - 37 * CHAR_COLS, 12 * CHAR_LINES, MSG_BOX_TEXT); - flush_block (3 * CHAR_COLS, 11 * CHAR_LINES - 1, - 37 * CHAR_COLS, 12 * CHAR_LINES); - - get_string (2, 11, 33, MAX_STRINGS); - print_character (3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); - do { main_cycle (); } while (game.input_mode == INPUT_GETSTRING); - close_window (); - - desc = game.strings[MAX_STRINGS]; - - sprintf (dstr, "Are you sure you want to save the game " - "described as:\n\n%s\n\nin slot %d?\n\n\n", - desc, slot); - - rc = selection_box (dstr, buttons); - - if (rc != 0) { - message_box ("Game NOT saved."); - return err_OK; - } - -// sprintf (path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", -// home, game.crc, game.id, slot); - sprintf (path, "%08d.sav", slot); - _D (_D_WARN "file is [%s]", path); - - save_game (path, desc); - - message_box ("Game saved."); - - return err_OK; -} - - -int loadgame_simple () -{ - char home[MAX_PATH], path[MAX_PATH]; - char buffer[64]; - int rc = 0; - -#if 0 - if (get_app_dir (home, MAX_PATH) < 0) { - message_box ("Error loading game."); - return err_BadFileOpen; - } - -// sprintf(path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", -// home, game.crc, game.id, 0); - sprintf(path,"%08d.sav",game.id); -#endif - sprintf (path,"00000756.SAV"); - sprintf (buffer,"trying to load %s",path); - message_box (buffer); - - erase_both(); - stop_sound(); - close_window(); - - if ((rc = load_game (path)) == err_OK) { - message_box ("Game restored."); - game.exit_all_logics = 1; - menu_enable_all(); - } else { - message_box ("Error restoring game."); - } - - return rc; -} - - -int loadgame_dialog () -{ - char home[MAX_PATH], path[MAX_PATH]; - int rc, slot = 0; - int hm, vm, hp, vp; /* box margins */ - int w; - - hm = 2; vm = 3; - hp = hm * CHAR_COLS; vp = vm * CHAR_LINES; - w = (40 - 2 * hm) - 1; - -#if 0 - if (get_app_dir (home, MAX_PATH) < 0) { - message_box ("Error loading game."); - return err_BadFileOpen; - } - -// sprintf (path, "%s/" DATA_DIR "/%05X.%s/", home, game.crc, game.id); -#endif - //sprintf (path, "%05X.%s", game.crc, game.id); - sprintf (path,""); - - erase_both(); - stop_sound(); - - draw_window (hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); - print_text ("Select a game which you wish to\nrestore:", - 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - print_text ("Press ENTER to select, ESC cancels", - 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - - slot = select_slot (path); - - if (slot < 0) { - message_box ("Game NOT restored."); - return err_OK; - } - -// sprintf(path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", -// home, game.crc, game.id, slot); - sprintf (path, "%08d.sav", slot); - - if ((rc = load_game (path)) == err_OK) { - message_box ("Game restored."); - game.exit_all_logics = 1; - menu_enable_all(); - } else { - message_box ("Error restoring game."); - } - - return rc; -} - -/* end: savegame.c */ +/* Sarien - A Sierra AGI resource interpreter engine + * Copyright (C) 1999-2003 Stuart George and Claudio Matsuoka + * + * $Id: savegame.c,v 1.82 2003/08/07 06:41:24 cmatsuoka Exp $ + * + * 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; see docs/COPYING for further details. + */ + +/* + * Savegame support by Vasyl Tsvirkunov + * Multi-slots by Claudio Matsuoka + */ + +#include +#include + +#if !defined(DREAMCAST) && !defined(CIBYL) && !defined(__MPW__) && !defined(PALMOS) +# ifndef __DICE__ +# include +# include +# endif +#endif + +#ifdef WIN32 +# include +#endif + +#include "sarien.h" +#include "agi.h" +#include "graphics.h" +#include "sprite.h" +#include "text.h" +#include "savegame.h" +#include "keyboard.h" +#include "menu.h" + +#undef fopen + +#if defined(__DICE__) || defined(WIN32) +# define MKDIR(a,b) mkdir(a) +#elif defined(CIBYL) +# define MKDIR(a,b) +#else +# define MKDIR(a,b) mkdir(a,b) +#endif + +/* Image stack support */ +struct image_stack_element { + UINT8 type; + UINT8 pad; + SINT16 parm1; + SINT16 parm2; + SINT16 parm3; + SINT16 parm4; + SINT16 parm5; + SINT16 parm6; + SINT16 parm7; +}; + +#define INITIAL_IMAGE_STACK_SIZE 32 +static int stack_size = 0; +static struct image_stack_element* image_stack = NULL; +static int image_stack_pointer = 0; + +void clear_image_stack(void) +{ + image_stack_pointer = 0; +} + +void release_image_stack(void) +{ + if(image_stack) + free(image_stack); + image_stack = NULL; + stack_size = image_stack_pointer = 0; +} + +void record_image_stack_call(UINT8 type, SINT16 p1, SINT16 p2, SINT16 p3, + SINT16 p4, SINT16 p5, SINT16 p6, SINT16 p7) +{ + struct image_stack_element* pnew; + + if (image_stack_pointer == stack_size) { + if (stack_size == 0) { /* first call */ + image_stack = (struct image_stack_element *)malloc(INITIAL_IMAGE_STACK_SIZE*sizeof(struct image_stack_element)); + stack_size = INITIAL_IMAGE_STACK_SIZE; + } else { /* has to grow */ + struct image_stack_element* new_stack; + new_stack = (struct image_stack_element *)malloc(2*stack_size*sizeof(struct image_stack_element)); + memcpy(new_stack, image_stack, stack_size*sizeof(struct image_stack_element)); + free(image_stack); + image_stack = new_stack; + stack_size *= 2; + } + } + + pnew = &image_stack[image_stack_pointer]; + image_stack_pointer++; + + pnew->type = type; + pnew->parm1 = p1; + pnew->parm2 = p2; + pnew->parm3 = p3; + pnew->parm4 = p4; + pnew->parm5 = p5; + pnew->parm6 = p6; + pnew->parm7 = p7; +} + +void replay_image_stack_call(UINT8 type, SINT16 p1, SINT16 p2, SINT16 p3, + SINT16 p4, SINT16 p5, SINT16 p6, SINT16 p7) +{ + switch(type) { + case ADD_PIC: + _D (_D_WARN "--- decoding picture %d ---", p1); + agi_load_resource (rPICTURE, p1); + decode_picture (p1, p2); + break; + case ADD_VIEW: + agi_load_resource (rVIEW, p1); + add_to_pic (p1, p2, p3, p4, p5, p6, p7); + break; + } +} + +/* */ + +static char* strSig = "Sarien:"; + +#ifndef PALMOS + +static void write_uint8(FILE* f, SINT8 val) +{ + fwrite(&val, 1, 1, f); +} + +static void write_sint16(FILE* f, SINT16 val) +{ + static UINT8 buf[2]; + buf[0] = (UINT8)((val>>8)&255); + buf[1] = (UINT8)(val&255); + fwrite(buf, 1, 2, f); +} + +static void write_uint16(FILE* f, UINT16 val) +{ + static UINT8 buf[2]; + buf[0] = (UINT8)((val>>8)&255); + buf[1] = (UINT8)(val&255); + fwrite(buf, 1, 2, f); +} + +static UINT8 read_uint8(FILE* f) +{ + static UINT8 buf[1]; + fread(buf, 1, 1, f); + return buf[0]; +} + +static UINT16 read_uint16(FILE* f) +{ + static UINT8 buf[2]; + fread(buf, 1, 2, f); + return (buf[0]<<8)|buf[1]; +} + +static SINT16 read_sint16(FILE* f) +{ + static UINT8 buf[2]; + fread(buf, 1, 2, f); + return (SINT16)((buf[0]<<8)|buf[1]); +} + + +static void write_string (FILE* f, char* s) +{ + write_sint16 (f, (SINT16)strlen(s)); + fwrite(s, 1, strlen(s), f); +} + +static void read_string (FILE* f, char* s) +{ + SINT16 size = read_sint16(f); + fread (s, 1, size, f); + s[size] = (char)0; +} + +static void write_bytes (FILE* f, char* s, SINT16 size) +{ + fwrite (s, 1, size, f); +} + +static void read_bytes (FILE* f, char* s, SINT16 size) +{ + fread (s, 1, size, f); +} + + +/* + * Version 0: view table has 64 entries + * Version 1: view table has 256 entries (needed in KQ3) + */ +#define SAVEGAME_VERSION 1 + +int save_game (char* s, char* d) +{ + SINT16 i; + struct image_stack_element* ptr = image_stack; + FILE* f = fopen (s, "wb"); + + if(!f) + return err_BadFileOpen; + + write_bytes (f, strSig, 8); + write_string (f, d); + + write_uint8 (f, (UINT8)SAVEGAME_VERSION); + write_uint8 (f, (UINT8)game.state); + /* game.name */ + write_string (f, game.id); + /* game.crc */ + + for (i = 0; i < MAX_FLAGS; i++) + write_uint8 (f, game.flags[i]); + for (i = 0; i < MAX_VARS; i++) + write_uint8 (f, game.vars[i]); + + write_sint16 (f, (SINT8)game.horizon); + write_sint16 (f, (SINT16)game.line_status); + write_sint16 (f, (SINT16)game.line_user_input); + write_sint16 (f, (SINT16)game.line_min_print); + /* game.cursor_pos */ + /* game.input_buffer */ + /* game.echo_buffer */ + /* game.keypress */ + write_sint16 (f, (SINT16)game.input_mode); + write_sint16 (f, (SINT16)game.lognum); + + write_sint16 (f, (SINT16)game.player_control); + write_sint16 (f, (SINT16)game.quit_prog_now); + write_sint16 (f, (SINT16)game.status_line); + write_sint16 (f, (SINT16)game.clock_enabled); + write_sint16 (f, (SINT16)game.exit_all_logics); + write_sint16 (f, (SINT16)game.picture_shown); + write_sint16 (f, (SINT16)game.has_prompt); + write_sint16 (f, (SINT16)game.game_flags); + + /* Reversed to keep compatibility with old savegames */ + write_sint16 (f, (SINT16)!game.input_enabled); + + for (i = 0; i < _HEIGHT; i++) + write_uint8 (f, game.pri_table[i]); + + /* game.msg_box_ticks */ + /* game.block */ + /* game.window */ + /* game.has_window */ + + write_sint16 (f, (SINT16)game.gfx_mode); + write_uint8 (f, game.cursor_char); + write_sint16 (f, (SINT16)game.color_fg); + write_sint16 (f, (SINT16)game.color_bg); + + /* game.hires (#ifdef USE_HIRES) */ + /* game.sbuf */ + /* game.ego_words */ + /* game.num_ego_words */ + + write_sint16 (f, (SINT16)game.num_objects); + for (i = 0; i < (SINT16)game.num_objects; i++) + write_sint16 (f, (SINT16)object_get_location(i)); + + /* game.ev_keyp */ + for (i = 0; i < MAX_STRINGS; i++) + write_string (f, game.strings[i]); + + /* record info about loaded resources */ + for (i = 0; i < MAX_DIRS; i++) { + write_uint8 (f, game.dir_logic[i].flags); + write_sint16 (f, (SINT16)game.logics[i].sIP); + write_sint16 (f, (SINT16)game.logics[i].cIP); + } + for (i = 0; i < MAX_DIRS; i++) + write_uint8(f, game.dir_pic[i].flags); + for (i = 0; i < MAX_DIRS; i++) + write_uint8(f, game.dir_view[i].flags); + for (i = 0; i < MAX_DIRS; i++) + write_uint8(f, game.dir_sound[i].flags); + + /* game.pictures */ + /* game.logics */ + /* game.views */ + /* game.sounds */ + + for(i = 0; i < MAX_VIEWTABLE; i++) { + struct vt_entry* v = &game.view_table[i]; + + write_uint8(f, v->step_time); + write_uint8(f, v->step_time_count); + write_uint8(f, v->entry); + write_sint16(f, v->x_pos); + write_sint16(f, v->y_pos); + write_uint8(f, v->current_view); + + /* v->view_data */ + + write_uint8(f, v->current_loop); + write_uint8(f, v->num_loops); + + /* v->loop_data */ + + write_uint8(f, v->current_cel); + write_uint8(f, v->num_cels); + + /* v->cel_data */ + /* v->cel_data_2 */ + + write_sint16(f, v->x_pos2); + write_sint16(f, v->y_pos2); + + /* v->s */ + + write_sint16(f, v->x_size); + write_sint16(f, v->y_size); + write_uint8(f, v->step_size); + write_uint8(f, v->cycle_time); + write_uint8(f, v->cycle_time_count); + write_uint8(f, v->direction); + + write_uint8(f, v->motion); + write_uint8(f, v->cycle); + write_uint8(f, v->priority); + + write_uint16(f, v->flags); + + write_uint8(f, v->parm1); + write_uint8(f, v->parm2); + write_uint8(f, v->parm3); + write_uint8(f, v->parm4); + } + + /* Save image stack */ + + for (i = 0; i < image_stack_pointer; i++) { + ptr = &image_stack[i]; + write_uint8 (f, ptr->type); + write_sint16 (f, ptr->parm1); + write_sint16 (f, ptr->parm2); + write_sint16 (f, ptr->parm3); + write_sint16 (f, ptr->parm4); + write_sint16 (f, ptr->parm5); + write_sint16 (f, ptr->parm6); + write_sint16 (f, ptr->parm7); + } + write_uint8(f, 0); + + fclose(f); + + return err_OK; +} + +int load_game(char* s) +{ + int i, ver, vt_entries = MAX_VIEWTABLE; + UINT8 t; + SINT16 parm[7]; + char sig[8]; + char id[8]; + char description[256]; + FILE *f = fopen(s, "rb"); + + if(!f) + return err_BadFileOpen; + + read_bytes(f, sig, 8); + if (strncmp (sig, strSig, 8)) { + fclose(f); + return err_BadFileOpen; + } + + read_string (f, description); + + ver = read_uint8(f); + if (ver == 0) + vt_entries = 64; + game.state = read_uint8(f); + /* game.name - not saved */ + read_string(f, id); + if(strcmp(id, game.id)) { + fclose(f); + return err_BadFileOpen; + } + /* game.crc - not saved */ + + for (i = 0; i < MAX_FLAGS; i++) + game.flags[i] = read_uint8(f); + for (i = 0; i < MAX_VARS; i++) + game.vars[i] = read_uint8(f); + + game.horizon = read_sint16(f); + game.line_status = read_sint16(f); + game.line_user_input = read_sint16(f); + game.line_min_print = read_sint16(f); + + /* These are never saved */ + game.cursor_pos = 0; + game.input_buffer[0] = 0; + game.echo_buffer[0] = 0; + game.keypress = 0; + + game.input_mode = read_sint16(f); + game.lognum = read_sint16(f); + + game.player_control = read_sint16(f); + game.quit_prog_now = read_sint16(f); + game.status_line = read_sint16(f); + game.clock_enabled = read_sint16(f); + game.exit_all_logics = read_sint16(f); + game.picture_shown = read_sint16(f); + game.has_prompt = read_sint16(f); + game.game_flags = read_sint16(f); + game.input_enabled = !read_sint16(f); + + for (i = 0; i < _HEIGHT; i++) + game.pri_table[i] = read_uint8(f); + + if(game.has_window) + close_window(); + game.msg_box_ticks = 0; + game.block.active = FALSE; + /* game.window - fixed by close_window() */ + /* game.has_window - fixed by close_window() */ + + game.gfx_mode = read_sint16(f); + game.cursor_char = read_uint8(f); + game.color_fg = read_sint16(f); + game.color_bg = read_sint16(f); + + /* game.hires (#ifdef USE_HIRES) - rebuilt from image stack */ + /* game.sbuf - rebuilt from image stack */ + + /* game.ego_words - fixed by clean_input */ + /* game.num_ego_words - fixed by clean_input */ + + game.num_objects = read_sint16(f); + for(i = 0; i < (SINT16)game.num_objects; i++) + object_set_location(i, read_sint16(f)); + + /* Those are not serialized */ + for (i = 0; i < MAX_DIRS; i++) { + game.ev_keyp[i].occured = FALSE; + } + + for (i = 0; i < MAX_STRINGS; i++) + read_string (f, game.strings[i]); + + for (i = 0; i < MAX_DIRS; i++) { + if(read_uint8(f) & RES_LOADED) + agi_load_resource (rLOGIC, i); + else + agi_unload_resource (rLOGIC, i); + game.logics[i].sIP = read_sint16(f); + game.logics[i].cIP = read_sint16(f); + } + + for (i = 0; i < MAX_DIRS; i++) { + if(read_uint8(f) & RES_LOADED) + agi_load_resource(rPICTURE, i); + else + agi_unload_resource(rPICTURE, i); + } + + for (i = 0; i < MAX_DIRS; i++) { + if(read_uint8(f) & RES_LOADED) + agi_load_resource(rVIEW, i); + else + agi_unload_resource(rVIEW, i); + } + + for(i = 0; i < MAX_DIRS; i++) { + if(read_uint8(f) & RES_LOADED) + agi_load_resource(rSOUND, i); + else + agi_unload_resource(rSOUND, i); + } + + /* game.pictures - loaded above */ + /* game.logics - loaded above */ + /* game.views - loaded above */ + /* game.sounds - loaded above */ + + for (i = 0; i < vt_entries; i++) { + struct vt_entry* v = &game.view_table[i]; + + v->step_time = read_uint8(f); + v->step_time_count = read_uint8(f); + v->entry = read_uint8(f); + v->x_pos = read_sint16(f); + v->y_pos = read_sint16(f); + v->current_view = read_uint8(f); + + /* v->view_data - fixed below */ + + v->current_loop = read_uint8(f); + v->num_loops = read_uint8(f); + + /* v->loop_data - fixed below */ + + v->current_cel = read_uint8(f); + v->num_cels = read_uint8(f); + + /* v->cel_data - fixed below */ + /* v->cel_data_2 - fixed below */ + + v->x_pos2 = read_sint16(f); + v->y_pos2 = read_sint16(f); + + /* v->s - fixed below */ + + v->x_size = read_sint16(f); + v->y_size = read_sint16(f); + v->step_size = read_uint8(f); + v->cycle_time = read_uint8(f); + v->cycle_time_count = read_uint8(f); + v->direction = read_uint8(f); + + v->motion = read_uint8(f); + v->cycle = read_uint8(f); + v->priority = read_uint8(f); + + v->flags = read_uint16(f); + + v->parm1 = read_uint8(f); + v->parm2 = read_uint8(f); + v->parm3 = read_uint8(f); + v->parm4 = read_uint8(f); + } + for (i = vt_entries; i < MAX_VIEWTABLE; i++) { + memset (&game.view_table[i], 0, sizeof (struct vt_entry)); + } + + /* Fix some pointers in viewtable */ + + for (i = 0; i < MAX_VIEWTABLE; i++) { + struct vt_entry* v = &game.view_table[i]; + + if(game.dir_view[v->current_view].offset == _EMPTY) + continue; + + if(!(game.dir_view[v->current_view].flags & RES_LOADED)) + agi_load_resource(rVIEW, v->current_view); + + set_view(v, v->current_view); /* Fix v->view_data */ + set_loop(v, v->current_loop); /* Fix v->loop_data */ + set_cel(v, v->current_cel); /* Fix v->cel_data */ + v->cel_data_2 = v->cel_data; + v->s = NULL; /* not sure if it is used... */ + } + + erase_both(); + + /* Clear input line */ + clear_screen(0); + write_status(); + + /* Recreate background from saved image stack */ + clear_image_stack(); + while ((t = read_uint8(f)) != 0) { + for (i = 0; i < 7; i++) + parm[i] = read_sint16(f); + replay_image_stack_call (t, parm[0], parm[1], parm[2], + parm[3], parm[4], parm[5], parm[6]); + } + + fclose(f); + + setflag(F_restore_just_ran, TRUE); + + game.has_prompt = 0; /* force input line repaint if necessary*/ + clean_input(); + + erase_both(); + blit_both(); + commit_both(); + show_pic(); + do_update(); + + return err_OK; +} +#endif /* PALMOS */ + +#define NUM_SLOTS 12 + +static int select_slot (char *path) +{ + int i, key, active = 0; + int rc = -1; + int hm = 2, vm = 3; /* box margins */ + char desc[NUM_SLOTS][40]; + + for (i = 0; i < NUM_SLOTS; i++) { + char name[MAX_PATH]; + FILE *f; + char sig[8]; + //sprintf (name, "%s/%08d.sav", path, i); + sprintf (name, "%08d.sav", i); + //printf("Opening %s\n", name); + f = fopen (name, "rb"); + if (f == NULL) { + strcpy (desc[i], " (empty slot)"); + } else { + read_bytes (f, sig, 8); + if (strncmp (sig, strSig, 8)) { + strcpy (desc[i], "(corrupt file)"); + } else { + read_string (f, desc[i]); + } + fclose(f); + } + } + + while (42) { + char dstr[64]; + for (i = 0; i < NUM_SLOTS; i++) { + sprintf (dstr, "[%-32.32s]", desc[i]); + print_text (dstr, 0, hm + 1, vm + 4 + i, + (40 - 2 * hm) - 1, + i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT, + i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR); + + } + + poll_timer (); /* msdos driver -> does nothing */ + key = do_poll_keyboard (); + if (!console_keyhandler (key)) { + switch (key) { + case KEY_ENTER: + rc = active; + strncpy (game.strings[MAX_STRINGS], + desc[i], MAX_STRINGLEN); + goto press; + case KEY_ESCAPE: + rc = -1; + goto getout; +#ifdef USE_MOUSE + case BUTTON_LEFT: + break; +#endif + case KEY_DOWN: + active++; + active %= NUM_SLOTS; + break; + case KEY_UP: + active--; + if (active < 0) + active = NUM_SLOTS - 1; + break; + } + } + console_cycle (); + } + +press: + _D (_D_WARN "Button pressed: %d", rc); + +getout: + close_window(); + return rc; +} + +int savegame_simple () +{ + char home[MAX_PATH], path[MAX_PATH]; + sprintf(path,"%08d.sav",game.id); + save_game (path, "save"); + + return err_OK; +} + + +int savegame_dialog () +{ + char home[MAX_PATH], path[MAX_PATH]; + char *desc; + char *buttons[] = { "Do as I say!", "I regret", NULL }; + char dstr[200]; + int rc, slot = 0; + int hm, vm, hp, vp; /* box margins */ + int w; + + hm = 2; vm = 3; + hp = hm * CHAR_COLS; vp = vm * CHAR_LINES; + w = (40 - 2 * hm) - 1; + +#if 0 + if (get_app_dir (home, MAX_PATH) < 0) { + message_box ("Couldn't save game."); + return err_BadFileOpen; + } + + /* DATADIR conflicts with ObjIdl.h in win32 SDK, renamed to DATA_DIR */ + sprintf (path, "%s/" DATA_DIR "/", home); + MKDIR (path, 0755); + sprintf (path, "%s/" DATA_DIR "/%05X.%s/", home, game.crc, game.id); + MKDIR (path, 0711); + +#endif + + erase_both (); + + draw_window (hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); + print_text ("Select a slot in which you wish to save the game:", + 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); + print_text ("Press ENTER to select, ESC cancels", + 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); + + slot = select_slot (path); + if (slot < 0) /* ESC pressed */ + return err_OK; + + /* Get savegame description */ + draw_window (hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp, + GFX_HEIGHT - vp - 9 * CHAR_LINES); + print_text ("Enter a description for this game:", + 0, hm + 1, vm + 6, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); + draw_rectangle (3 * CHAR_COLS, 11 * CHAR_LINES - 1, + 37 * CHAR_COLS, 12 * CHAR_LINES, MSG_BOX_TEXT); + flush_block (3 * CHAR_COLS, 11 * CHAR_LINES - 1, + 37 * CHAR_COLS, 12 * CHAR_LINES); + + get_string (2, 11, 33, MAX_STRINGS); + print_character (3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); + do { main_cycle (); } while (game.input_mode == INPUT_GETSTRING); + close_window (); + + desc = game.strings[MAX_STRINGS]; + + sprintf (dstr, "Are you sure you want to save the game " + "described as:\n\n%s\n\nin slot %d?\n\n\n", + desc, slot); + + rc = selection_box (dstr, buttons); + + if (rc != 0) { + message_box ("Game NOT saved."); + return err_OK; + } + +// sprintf (path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", +// home, game.crc, game.id, slot); + sprintf (path, "%08d.sav", slot); + _D (_D_WARN "file is [%s]", path); + + save_game (path, desc); + + message_box ("Game saved."); + + return err_OK; +} + + +int loadgame_simple () +{ + char home[MAX_PATH], path[MAX_PATH]; + char buffer[64]; + int rc = 0; + +#if 0 + if (get_app_dir (home, MAX_PATH) < 0) { + message_box ("Error loading game."); + return err_BadFileOpen; + } + +// sprintf(path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", +// home, game.crc, game.id, 0); + sprintf(path,"%08d.sav",game.id); +#endif + sprintf (path,"00000756.SAV"); + sprintf (buffer,"trying to load %s",path); + message_box (buffer); + + erase_both(); + stop_sound(); + close_window(); + + if ((rc = load_game (path)) == err_OK) { + message_box ("Game restored."); + game.exit_all_logics = 1; + menu_enable_all(); + } else { + message_box ("Error restoring game."); + } + + return rc; +} + + +int loadgame_dialog () +{ + char home[MAX_PATH], path[MAX_PATH]; + int rc, slot = 0; + int hm, vm, hp, vp; /* box margins */ + int w; + + hm = 2; vm = 3; + hp = hm * CHAR_COLS; vp = vm * CHAR_LINES; + w = (40 - 2 * hm) - 1; + +#if 0 + if (get_app_dir (home, MAX_PATH) < 0) { + message_box ("Error loading game."); + return err_BadFileOpen; + } + +// sprintf (path, "%s/" DATA_DIR "/%05X.%s/", home, game.crc, game.id); +#endif + //sprintf (path, "%05X.%s", game.crc, game.id); + sprintf (path,""); + + erase_both(); + stop_sound(); + + draw_window (hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); + print_text ("Select a game which you wish to\nrestore:", + 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); + print_text ("Press ENTER to select, ESC cancels", + 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); + + slot = select_slot (path); + + if (slot < 0) { + message_box ("Game NOT restored."); + return err_OK; + } + +// sprintf(path, "%s/" DATA_DIR "/%05X.%s/%08d.sav", +// home, game.crc, game.id, slot); + sprintf (path, "%08d.sav", slot); + + if ((rc = load_game (path)) == err_OK) { + message_box ("Game restored."); + game.exit_all_logics = 1; + menu_enable_all(); + } else { + message_box ("Error restoring game."); + } + + return rc; +} + +/* end: savegame.c */ diff --git a/sound.c b/sound.c index aaceb33..2efb2dd 100644 --- a/sound.c +++ b/sound.c @@ -412,34 +412,14 @@ static void stop_note (int i) static void play_note (int i, int freq, int len, int vol) { - if (!getflag (F_sound_on)) - vol = 0; - else if (vol && opt.soundemu == SOUND_EMU_PC) - vol = 160; - -#ifdef USE_PCM_SOUND - chn[i].phase = 0; -#endif - +if(i==0) + SendBeep(freq,len); +/* chn[i].freq = freq; chn[i].vol = vol; chn[i].env = 0x10000; chn[i].adsr = AGI_SOUND_ENV_ATTACK; - -#ifdef CIBYL - if (i == 0) { - int exc = 0; - int note = freq_to_note(freq); - - NOPH_try(NOPH_setter_exception_handler, (void*)&exc) { - NOPH_Manager_playTone(note, len + 1, (vol * 100) / 255); - } NOPH_catch(); - if (exc) { - printf("playTone threw an exception: note %d, len %d, vol %d\n", - note, len, (vol * 100) / 255); - } - } -#endif +*/ } @@ -548,7 +528,8 @@ void play_agi_sound () { int i, freq; - for (playing = i = 0; i < (opt.soundemu == SOUND_EMU_PC ? 1 : 4); i++) { +// for (playing = i = 0; i < (opt.soundemu == SOUND_EMU_PC ? 1 : 4); i++) { + for (playing = i = 0; i < 4; i++) { playing |= !chn[i].end; if (chn[i].end) @@ -591,14 +572,6 @@ void play_sound () if (endflag == -1) return; -#ifdef USE_IIGS_SOUND - if (chn[0].type == AGI_SOUND_MIDI) { - /* play_midi_sound (); */ - playing = 0; - } else if (chn[0].type == AGI_SOUND_SAMPLE) { - play_sample_sound (); - } else -#endif play_agi_sound (); if (!playing) { @@ -615,190 +588,4 @@ void play_sound () } -#ifdef USE_PCM_SOUND - -UINT32 mix_sound (void) -{ - register int i, p; - SINT16 *src; - int c, b, m; - - memset (snd_buffer, 0, BUFFER_SIZE << 1); - - for (c = 0; c < NUM_CHANNELS; c++) { - if (!chn[c].vol) - continue; - - m = chn[c].flags & AGI_SOUND_ENVELOPE ? - chn[c].vol * chn[c].env >> 16 : - chn[c].vol; - - if (chn[c].type != AGI_SOUND_4CHN || c != 3) { - src = chn[c].ins; - - p = chn[c].phase; - for (i = 0; i < BUFFER_SIZE; i++) { - b = src[p >> 8]; -#ifdef USE_INTERPOLATION - b += ((src[((p >> 8) + 1) % chn[c].size] - - src[p >> 8]) * (p & 0xff)) >> 8; -#endif - snd_buffer[i] += (b * m) >> 4; - - p += (UINT32)118600 * 4 / chn[c].freq; - - /* FIXME */ - if (chn[c].flags & AGI_SOUND_LOOP) { - p %= chn[c].size << 8; - } else { - if (p >= chn[c].size << 8) { - p = chn[c].vol = 0; - chn[c].end = 1; - break; - } - } - - } - chn[c].phase = p; - } else { - /* Add white noise */ - for (i = 0; i < BUFFER_SIZE; i++) { - b = rnd(256) - 128; - snd_buffer[i] += (b * m) >> 4; - } - } - - switch (chn[c].adsr) { - case AGI_SOUND_ENV_ATTACK: - /* not implemented */ - chn[c].adsr = AGI_SOUND_ENV_DECAY; - break; - case AGI_SOUND_ENV_DECAY: - if (chn[c].env > chn[c].vol * ENV_SUSTAIN + ENV_DECAY) { - chn[c].env -= ENV_DECAY; - } else { - chn[c].env = chn[c].vol * ENV_SUSTAIN; - chn[c].adsr = AGI_SOUND_ENV_SUSTAIN; - } - break; - case AGI_SOUND_ENV_SUSTAIN: - break; - case AGI_SOUND_ENV_RELEASE: - if (chn[c].env >= ENV_RELEASE) { - chn[c].env -= ENV_RELEASE; - } else { - chn[c].env = 0; - } - } - } - - return BUFFER_SIZE; -} - - -#ifdef USE_IIGS_SOUND - -#if 0 -int load_instruments (char *fname) -{ - FILE *fp; - int i, j, k; - struct sound_instrument ai; - int num_wav; - char *path; - - path = fixpath (NO_GAMEDIR, "sierrast"); - - if ((fp = fopen (path, "rb")) == NULL) - return err_BadFileOpen; - report ("Loading samples: %s\n", path); - - if ((wave = malloc (0x10000 * 2)) == NULL) - return err_NotEnoughMemory; - - fread (wave, 0x10000, 1, fp); - fclose (fp); - for (i = 0x10000; i--; ) { - ((SINT16 *)wave)[i] = 2 * ((SINT16)wave[i] - 128); - } - -fp = fopen ("bla", "w"); -fwrite (wave, 2, 0x10000, fp); -fclose (fp); - - fixpath (NO_GAMEDIR, fname); - report ("Loading instruments: %s\n", path); - - if ((fp = fopen (path, "rb")) == NULL) - return err_BadFileOpen; - - fseek (fp, 0x8469, SEEK_SET); - -for (num_wav = j = 0; j < 40; j++) { - fread (&ai, 1, 32, fp); - - if (ai.env[0].bp > 0x7f) - break; - -#if 0 - printf ("Instrument %d loaded ----------------\n", j); - printf ("Envelope:\n"); - for (i = 0; i < 8; i++) - printf ("[seg %d]: BP %02x Inc %04x\n", - i, ai.env[i].bp, ((int)ai.env[i].inc_hi << 8) | - ai.env[i].inc_lo); - printf ("rel seg: %d, pri inc: %d, bend range: %d, vib dep: %d, " - "vib spd: %d\n", ai.relseg, ai.priority, ai.bendrange, - ai.vibdepth, ai.vibspeed); - printf ("A wave count: %d, B wave count: %d\n", ai.wac, ai.wbc); -#endif - - for (k = 0; k < ai.wac; k++, num_wav++) { - fread (&ai.wal[k], 1, 6, fp); -#if 0 - printf ("[A %d of %d] top: %02x, wave address: %02x, " - "size: %02x, mode: %02x, relPitch: %04x\n", - k + 1, ai.wac, ai.wal[k].top, ai.wal[k].addr, - ai.wal[k].size, ai.wal[k].mode, - ((int)ai.wal[k].rel_hi << 8) | ai.wal[k].rel_lo); -#endif - } - - for (k = 0; k < ai.wbc; k++, num_wav++) { - fread (&ai.wbl[k], 1, 6, fp); -#if 0 - printf ("[B %d of %d] top: %02x, wave address: %02x, " - "size: %02x, mode: %02x, relPitch: %04x\n", - k + 1, ai.wbc, ai.wbl[k].top, ai.wbl[k].addr, - ai.wbl[k].size, ai.wbl[k].mode, - ((int)ai.wbl[k].rel_hi << 8) | ai.wbl[k].rel_lo); -#endif - } - waveaddr[j] = 256 * ai.wal[0].addr; - wavesize[j] = 256 * (1 << ((ai.wal[0].size) & 0x07)); -#if 1 - printf ("%d addr = %d\n", j, waveaddr[j]); - printf (" size = %d\n", wavesize[j]); -#endif -} - - num_instruments = j; - printf ("%d Ensoniq 5503 instruments loaded. (%d waveforms)\n", - num_instruments, num_wav); - - fclose(fp); - - return err_OK; -} - - -void unload_instruments () -{ - free (instruments); -} -#endif - -#endif /* USE_IIGS_SOUND */ - -#endif /* USE_PCM_SOUND */