Merged revisions 33052-33053,33056-33058,33061-33064,33068,33070,33072,33075,33078-33079,33083,33086-33087,33089,33094-33096,33098-33099,33104,33108-33109,33114-33117,33120,33135-33146,33160,33162,33165,33167-33169 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r33183
This commit is contained in:
commit
09f4fd946e
70 changed files with 4241 additions and 930 deletions
|
@ -132,8 +132,7 @@ bail:
|
||||||
return MERR_DEVICE_NOT_AVAILABLE;
|
return MERR_DEVICE_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_QT::close()
|
void MidiDriver_QT::close() {
|
||||||
{
|
|
||||||
MidiDriver_MPU401::close();
|
MidiDriver_MPU401::close();
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
|
@ -248,8 +247,7 @@ void MidiDriver_QT::setPitchBendRange (byte channel, uint range) {
|
||||||
NASetController(qtNoteAllocator, qtNoteChannel[channel], kControllerPitchBend, theBend);
|
NASetController(qtNoteAllocator, qtNoteChannel[channel], kControllerPitchBend, theBend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_QT::dispose()
|
void MidiDriver_QT::dispose() {
|
||||||
{
|
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (qtNoteChannel[i] != 0)
|
if (qtNoteChannel[i] != 0)
|
||||||
NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]);
|
NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]);
|
||||||
|
|
|
@ -19,16 +19,17 @@ RM = rm -f
|
||||||
srcdir = ../../..
|
srcdir = ../../..
|
||||||
VPATH = $(srcdir)
|
VPATH = $(srcdir)
|
||||||
INCDIR = ../../../
|
INCDIR = ../../../
|
||||||
|
DEPDIR = .deps
|
||||||
|
|
||||||
DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_MPEG2 -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar
|
DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_MPEG2 -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar
|
||||||
|
|
||||||
# PS2SDK-Ports from ps2dev.org's SVN repository for libmad, zlib and ucl
|
# PS2SDK-Ports from ps2dev.org's SVN repository for libmad, zlib and ucl
|
||||||
PS2SDK_PORTS = /home/robby/libStuffNew/ps2sdk-ports
|
PS2SDK_PORTS = /mnt/winxp/scummvm/ports
|
||||||
PS2SDK_PORTS_INCS = /ucl /zlib/include /libmad/ee/include
|
PS2SDK_PORTS_INCS = /ucl /zlib/include /libmad/ee/include
|
||||||
PS2SDK_PORTS_LIBS = /ucl /zlib/lib /libmad/ee/lib
|
PS2SDK_PORTS_LIBS = /ucl /zlib/lib /libmad/ee/lib
|
||||||
|
|
||||||
# we also need SjPcm, Tremor and libmpeg2
|
# we also need SjPcm, Tremor and libmpeg2
|
||||||
MORE_LIBS_DIR = /home/robby/libStuff
|
MORE_LIBS_DIR = /mnt/winxp/scummvm/ports
|
||||||
MORE_LIBS_INCS = /SjPcm/ee/src /mpeg2dec/include /tremor
|
MORE_LIBS_INCS = /SjPcm/ee/src /mpeg2dec/include /tremor
|
||||||
MORE_LIBS_LIBS = /SjPcm/ee/lib /mpeg2dec/libmpeg2 /tremor/tremor
|
MORE_LIBS_LIBS = /SjPcm/ee/lib /mpeg2dec/libmpeg2 /tremor/tremor
|
||||||
|
|
||||||
|
|
|
@ -340,8 +340,6 @@ FILE *ps2_fopen(const char *fname, const char *mode) {
|
||||||
assert(cacheListSema >= 0);
|
assert(cacheListSema >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("ps2_fopen: %s, %s\n", fname, mode);
|
|
||||||
|
|
||||||
if (((mode[0] != 'r') && (mode[0] != 'w')) || ((mode[1] != '\0') && (mode[1] != 'b'))) {
|
if (((mode[0] != 'r') && (mode[0] != 'w')) || ((mode[1] != '\0') && (mode[1] != 'b'))) {
|
||||||
printf("unsupported mode \"%s\" for file \"%s\"\n", mode, fname);
|
printf("unsupported mode \"%s\" for file \"%s\"\n", mode, fname);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -363,6 +361,8 @@ FILE *ps2_fopen(const char *fname, const char *mode) {
|
||||||
} else {
|
} else {
|
||||||
// Regular access to one of the devices
|
// Regular access to one of the devices
|
||||||
|
|
||||||
|
printf("ps2_fopen = %s\n", fname); // romeo : temp
|
||||||
|
|
||||||
if (!rdOnly)
|
if (!rdOnly)
|
||||||
return NULL; // we only provide readaccess for cd,dvd,hdd,usb
|
return NULL; // we only provide readaccess for cd,dvd,hdd,usb
|
||||||
|
|
||||||
|
@ -378,19 +378,22 @@ FILE *ps2_fopen(const char *fname, const char *mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 cacheId = -1;
|
int64 cacheId = -1;
|
||||||
if (rdOnly && tocManager.haveEntries())
|
if (tocManager.haveEntries())
|
||||||
cacheId = tocManager.fileExists(fname);
|
cacheId = tocManager.fileExists(fname);
|
||||||
|
|
||||||
if (cacheId != 0) {
|
if (cacheId != 0) {
|
||||||
Ps2File *file = findInCache(cacheId);
|
Ps2File *file = findInCache(cacheId);
|
||||||
if (file)
|
if (file) {
|
||||||
|
printf(" findInCache(%x)\n", cacheId); // romeo : temp
|
||||||
return (FILE*)file;
|
return (FILE*)file;
|
||||||
|
}
|
||||||
|
|
||||||
bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun");
|
bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun");
|
||||||
file = new Ps2ReadFile(cacheId, isAudioFile);
|
file = new Ps2ReadFile(cacheId, isAudioFile);
|
||||||
|
|
||||||
if (file->open(fname)) {
|
if (file->open(fname)) {
|
||||||
openFileCount++;
|
openFileCount++;
|
||||||
|
printf(" new cacheID = %x\n", cacheId); // romeo : temp
|
||||||
return (FILE*)file;
|
return (FILE*)file;
|
||||||
} else
|
} else
|
||||||
delete file;
|
delete file;
|
||||||
|
@ -579,7 +582,7 @@ void TocManager::readEntries(const char *root) {
|
||||||
}
|
}
|
||||||
char readPath[256];
|
char readPath[256];
|
||||||
sprintf(readPath, "%s/", _root);
|
sprintf(readPath, "%s/", _root);
|
||||||
printf("readDir: %s\n", readPath);
|
printf("readDir: %s (root: %s )\n", readPath, root);
|
||||||
readDir(readPath, &_rootNode, 0);
|
readDir(readPath, &_rootNode, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,28 +590,62 @@ void TocManager::readDir(const char *path, TocNode **node, int level) {
|
||||||
if (level <= 2) { // we don't scan deeper than that
|
if (level <= 2) { // we don't scan deeper than that
|
||||||
iox_dirent_t dirent;
|
iox_dirent_t dirent;
|
||||||
int fd = fio.dopen(path);
|
int fd = fio.dopen(path);
|
||||||
if (fd >= 0) {
|
TocNode *eNode = NULL; // = *node; // entry node
|
||||||
while (fio.dread(fd, &dirent) > 0)
|
bool first = true;
|
||||||
if (dirent.name[0] != '.') { // skip '.' and '..'
|
|
||||||
*node = new TocNode;
|
|
||||||
(*node)->sub = (*node)->next = NULL;
|
|
||||||
|
|
||||||
|
printf("path=%s - level=%d fd=%d\n", path, level, fd); // romeo : temp
|
||||||
|
if (fd >= 0) {
|
||||||
|
while (fio.dread(fd, &dirent) > 0) {
|
||||||
|
if (dirent.name[0] != '.') { // skip '.' & '..' - romeo : check
|
||||||
|
// --- do we have them on PS2?
|
||||||
|
*node = new TocNode;
|
||||||
|
if (first) {
|
||||||
|
eNode = *node;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
(*node)->sub = (*node)->next = NULL;
|
||||||
(*node)->nameLen = strlen(dirent.name);
|
(*node)->nameLen = strlen(dirent.name);
|
||||||
memcpy((*node)->name, dirent.name, (*node)->nameLen + 1);
|
memcpy((*node)->name, dirent.name, (*node)->nameLen + 1);
|
||||||
|
|
||||||
if (dirent.stat.mode & FIO_S_IFDIR) { // directory
|
if (dirent.stat.mode & FIO_S_IFDIR) {
|
||||||
(*node)->isDir = true;
|
(*node)->isDir = true;
|
||||||
char nextPath[256];
|
printf("dirent.name = %s [DIR]\n", dirent.name);
|
||||||
sprintf(nextPath, "%s%s/", path, dirent.name);
|
}
|
||||||
readDir(nextPath, &((*node)->sub), level + 1);
|
else {
|
||||||
} else
|
|
||||||
(*node)->isDir = false;
|
(*node)->isDir = false;
|
||||||
|
printf("dirent.name = %s\n", dirent.name);
|
||||||
|
}
|
||||||
|
|
||||||
node = &((*node)->next);
|
node = &((*node)->next);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fio.dclose(fd);
|
fio.dclose(fd);
|
||||||
} else
|
}
|
||||||
printf("Can't open path: %s\n", path);
|
|
||||||
|
TocNode *iNode = eNode;
|
||||||
|
char nextPath[256];
|
||||||
|
|
||||||
|
while (iNode) {
|
||||||
|
if (iNode->isDir == true) {
|
||||||
|
sprintf(nextPath, "%s%s/", path, iNode->name);
|
||||||
|
readDir(nextPath, &(iNode->sub), level + 1);
|
||||||
|
}
|
||||||
|
iNode = iNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Wizard of Oz' trick (to get all games running from USB on PS2):
|
||||||
|
|
||||||
|
1. Make a list of files / dirs in level #0 (dclose before continuing)
|
||||||
|
|
||||||
|
2. Go through the dirs : dopen / dread them / mark dirs / dclose
|
||||||
|
|
||||||
|
It's a safe recursion, cause it recurses on 'isDir' nodes
|
||||||
|
after dclosing the higher hierarchy
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 TocManager::fileExists(const char *name) {
|
int64 TocManager::fileExists(const char *name) {
|
||||||
|
|
30
backends/platform/ps2/iop/rpckbd/Makefile
Normal file
30
backends/platform/ps2/iop/rpckbd/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# _____ ___ ____ ___ ____
|
||||||
|
# ____| | ____| | | |____|
|
||||||
|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
|
||||||
|
# Licenced under Academic Free License version 2.0
|
||||||
|
# Review ps2sdk README & LICENSE files for further details.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
|
||||||
|
IOP_OBJS_DIR = obj/
|
||||||
|
IOP_BIN_DIR = bin/
|
||||||
|
IOP_SRC_DIR = src/
|
||||||
|
IOP_INC_DIR = include/
|
||||||
|
|
||||||
|
IOP_BIN=bin/rpckbd.irx
|
||||||
|
IOP_OBJS=obj/ps2kbd.o obj/imports.o
|
||||||
|
|
||||||
|
IOP_CFLAGS=-Wall
|
||||||
|
IOP_INCS += -I$(PS2SDKSRC)/iop/usb/usbd/include
|
||||||
|
|
||||||
|
all: $(IOP_OBJS_DIR) $(IOP_BIN_DIR) $(IOP_BIN)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f -r $(IOP_OBJS_DIR) $(IOP_BIN_DIR)
|
||||||
|
|
||||||
|
include $(PS2SDKSRC)/Defs.make
|
||||||
|
include $(PS2SDKSRC)/iop/Rules.make
|
||||||
|
include $(PS2SDKSRC)/iop/Rules.release
|
90
backends/platform/ps2/iop/rpckbd/include/ps2kbd.h
Normal file
90
backends/platform/ps2/iop/rpckbd/include/ps2kbd.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
# _____ ___ ____ ___ ____
|
||||||
|
# ____| | ____| | | |____|
|
||||||
|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
|
||||||
|
# Licenced under Academic Free License version 2.0
|
||||||
|
# Review ps2sdk README & LICENSE files for further details.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
# USB Keyboard Driver for PS2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PS2KBD_H__
|
||||||
|
#define __PS2KBD_H__
|
||||||
|
|
||||||
|
#define PS2KBD_RPC_ID 0xb0b0b80
|
||||||
|
|
||||||
|
#define PS2KBD_LED_NUMLOCK 1
|
||||||
|
#define PS2KBD_LED_CAPSLOCK 2
|
||||||
|
#define PS2KBD_LED_SCRLOCK 4
|
||||||
|
#define PS2KBD_LED_COMPOSE 8
|
||||||
|
#define PS2KBD_LED_KANA 16
|
||||||
|
|
||||||
|
#define PS2KBD_LED_MASK 0x1F;
|
||||||
|
|
||||||
|
#define PS2KBD_ESCAPE_KEY 0x1B
|
||||||
|
|
||||||
|
#define PS2KBD_LEFT_CTRL (1 << 0)
|
||||||
|
#define PS2KBD_LEFT_SHIFT (1 << 1)
|
||||||
|
#define PS2KBD_LEFT_ALT (1 << 2)
|
||||||
|
#define PS2KBD_LEFT_GUI (1 << 3)
|
||||||
|
#define PS2KBD_RIGHT_CTRL (1 << 4)
|
||||||
|
#define PS2KBD_RIGHT_SHIFT (1 << 5)
|
||||||
|
#define PS2KBD_RIGHT_ALT (1 << 6)
|
||||||
|
#define PS2KBD_RIGHT_GUI (1 << 7)
|
||||||
|
|
||||||
|
#define PS2KBD_CTRL (PS2KBD_LEFT_CTRL | PS2KBD_RIGHT_CTRL)
|
||||||
|
#define PS2KBD_SHIFT (PS2KBD_LEFT_SHIFT | PS2KBD_RIGHT_SHIFT)
|
||||||
|
#define PS2KBD_ALT (PS2KBD_LEFT_ALT | PS2KBD_RIGHT_ALT)
|
||||||
|
#define PS2KBD_GUI (PS2KBD_LEFT_GUI | PS2KBD_RIGHT_GUI)
|
||||||
|
|
||||||
|
#define PS2KBD_RAWKEY_UP 0xF0
|
||||||
|
#define PS2KBD_RAWKEY_DOWN 0xF1
|
||||||
|
|
||||||
|
typedef struct _kbd_rawkey {
|
||||||
|
u8 state;
|
||||||
|
u8 key;
|
||||||
|
} kbd_rawkey __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define PS2KBD_READMODE_NORMAL 1
|
||||||
|
#define PS2KBD_READMODE_RAW 2
|
||||||
|
|
||||||
|
/* Notes on read mode */
|
||||||
|
/* In normal readmode (default) read multiples of 1 character off the keyboard file. These are
|
||||||
|
processed by the keymaps so that you get back ASCII data */
|
||||||
|
/* In raw readmode must read multiples of 2. First byte indicates state (i.e. Up or Down)
|
||||||
|
Second byte is the USB key code for that key. This table is presented in the USB HID Usage Tables manaual
|
||||||
|
from usb.org */
|
||||||
|
|
||||||
|
#define PS2KBD_KEYMAP_SIZE 256
|
||||||
|
|
||||||
|
typedef struct _kbd_keymap
|
||||||
|
|
||||||
|
{
|
||||||
|
u8 keymap[PS2KBD_KEYMAP_SIZE];
|
||||||
|
u8 shiftkeymap[PS2KBD_KEYMAP_SIZE];
|
||||||
|
u8 keycap[PS2KBD_KEYMAP_SIZE];
|
||||||
|
} kbd_keymap;
|
||||||
|
|
||||||
|
|
||||||
|
/* IRPC function numbers */
|
||||||
|
#define KBD_RPC_SETREADMODE 1 /* Sets up keymapped or raw mode */
|
||||||
|
#define KBD_RPC_SETLEDS 2 /* Sets the LED state for ALL keyboards connected */
|
||||||
|
#define KBD_RPC_SETREPEATRATE 3 /* Sets the repeat rate of the keyboard */
|
||||||
|
#define KBD_RPC_SETKEYMAP 4 /* Sets the keymap for the standard keys, non shifted and shifted */
|
||||||
|
#define KBD_RPC_SETCTRLMAP 5 /* Sets the control key mapping */
|
||||||
|
#define KBD_RPC_SETALTMAP 6 /* Sets the alt key mapping */
|
||||||
|
#define KBD_RPC_SETSPECIALMAP 7 /* Sets the special key mapping */
|
||||||
|
#define KBD_RPC_FLUSHBUFFER 9 /* Flush the internal buffer, probably best after a keymap change */
|
||||||
|
#define KBD_RPC_RESETKEYMAP 10 /* Reset keymaps to default states */
|
||||||
|
#define KBD_RPC_READKEY 11
|
||||||
|
#define KBD_RPC_READRAW 12
|
||||||
|
|
||||||
|
/* Note on keymaps. In normal keymap a 0 would indicate no key */
|
||||||
|
/* Key maps are represented by 3 256*8bit tables. First table maps USB key to a char when not shifted */
|
||||||
|
/* Second table maps USB key to a char when shifted */
|
||||||
|
/* Third table contains boolean values. If 1 then the key is shifted/unshifted in capslock, else capslock is ignored */
|
||||||
|
|
||||||
|
#endif
|
58
backends/platform/ps2/iop/rpckbd/src/imports.lst
Normal file
58
backends/platform/ps2/iop/rpckbd/src/imports.lst
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
sysclib_IMPORTS_start
|
||||||
|
I_memset
|
||||||
|
I_strcmp
|
||||||
|
I_memcpy
|
||||||
|
sysclib_IMPORTS_end
|
||||||
|
|
||||||
|
loadcore_IMPORTS_start
|
||||||
|
I_FlushDcache
|
||||||
|
loadcore_IMPORTS_end
|
||||||
|
|
||||||
|
sifcmd_IMPORTS_start
|
||||||
|
I_sceSifInitRpc
|
||||||
|
I_sceSifSetRpcQueue
|
||||||
|
I_sceSifRegisterRpc
|
||||||
|
I_sceSifRpcLoop
|
||||||
|
sifcmd_IMPORTS_end
|
||||||
|
|
||||||
|
stdio_IMPORTS_start
|
||||||
|
I_printf
|
||||||
|
stdio_IMPORTS_end
|
||||||
|
|
||||||
|
thsemap_IMPORTS_start
|
||||||
|
I_CreateSema
|
||||||
|
I_SignalSema
|
||||||
|
I_WaitSema
|
||||||
|
I_PollSema
|
||||||
|
I_DeleteSema
|
||||||
|
thsemap_IMPORTS_end
|
||||||
|
|
||||||
|
thbase_IMPORTS_start
|
||||||
|
I_StartThread
|
||||||
|
I_CreateThread
|
||||||
|
I_USec2SysClock
|
||||||
|
I_iSetAlarm
|
||||||
|
I_SetAlarm
|
||||||
|
I_CancelAlarm
|
||||||
|
thbase_IMPORTS_end
|
||||||
|
|
||||||
|
thevent_IMPORTS_start
|
||||||
|
I_WaitEventFlag
|
||||||
|
I_iSetEventFlag
|
||||||
|
I_CreateEventFlag
|
||||||
|
thevent_IMPORTS_end
|
||||||
|
|
||||||
|
sysmem_IMPORTS_start
|
||||||
|
I_AllocSysMemory
|
||||||
|
I_FreeSysMemory
|
||||||
|
sysmem_IMPORTS_end
|
||||||
|
|
||||||
|
usbd_IMPORTS_start
|
||||||
|
I_UsbGetDeviceStaticDescriptor
|
||||||
|
I_UsbOpenEndpoint
|
||||||
|
I_UsbSetDevicePrivateData
|
||||||
|
I_UsbTransfer
|
||||||
|
I_UsbRegisterDriver
|
||||||
|
usbd_IMPORTS_end
|
||||||
|
|
35
backends/platform/ps2/iop/rpckbd/src/irx_imports.h
Normal file
35
backends/platform/ps2/iop/rpckbd/src/irx_imports.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
# _____ ___ ____ ___ ____
|
||||||
|
# ____| | ____| | | |____|
|
||||||
|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
|
||||||
|
# Licenced under Academic Free License version 2.0
|
||||||
|
# Review ps2sdk README & LICENSE files for further details.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
# Defines all IRX imports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOP_IRX_IMPORTS_H
|
||||||
|
#define IOP_IRX_IMPORTS_H
|
||||||
|
|
||||||
|
#include "irx.h"
|
||||||
|
|
||||||
|
/* Please keep these in alphabetical order! */
|
||||||
|
#include "dmacman.h"
|
||||||
|
#include "intrman.h"
|
||||||
|
#include "libsd.h"
|
||||||
|
#include "loadcore.h"
|
||||||
|
#include "sifcmd.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "sysclib.h"
|
||||||
|
#include "sysmem.h"
|
||||||
|
#include "thbase.h"
|
||||||
|
#include "thevent.h"
|
||||||
|
#include "thmsgbx.h"
|
||||||
|
#include "thsemap.h"
|
||||||
|
#include "usbd.h"
|
||||||
|
#include "vblank.h"
|
||||||
|
|
||||||
|
#endif /* IOP_IRX_IMPORTS_H */
|
1199
backends/platform/ps2/iop/rpckbd/src/ps2kbd.c
Normal file
1199
backends/platform/ps2/iop/rpckbd/src/ps2kbd.c
Normal file
File diff suppressed because it is too large
Load diff
1579
backends/platform/ps2/iop/rpckbd/src/us_keymap.h
Normal file
1579
backends/platform/ps2/iop/rpckbd/src/us_keymap.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -43,7 +43,7 @@ IrxFile irxFiles[] = {
|
||||||
{ "PADMAN", BIOS, NOTHING, NULL, 0 },
|
{ "PADMAN", BIOS, NOTHING, NULL, 0 },
|
||||||
{ "LIBSD", BIOS, NOTHING, NULL, 0 },
|
{ "LIBSD", BIOS, NOTHING, NULL, 0 },
|
||||||
|
|
||||||
{ "IOMANX.IRX", SYSTEM | NOT_HOST, NOTHING, NULL, 0 }, // already loaded by ps2link
|
{ "IOMANX.IRX", SYSTEM /*| NOT_HOST*/, NOTHING, NULL, 0 }, // already loaded by ps2link
|
||||||
{ "FILEXIO.IRX", SYSTEM, NOTHING, NULL, 0 },
|
{ "FILEXIO.IRX", SYSTEM, NOTHING, NULL, 0 },
|
||||||
{ "CODYVDFS.IRX", SYSTEM, NOTHING, NULL, 0 },
|
{ "CODYVDFS.IRX", SYSTEM, NOTHING, NULL, 0 },
|
||||||
{ "SJPCM.IRX", SYSTEM, NOTHING, NULL, 0 },
|
{ "SJPCM.IRX", SYSTEM, NOTHING, NULL, 0 },
|
||||||
|
|
|
@ -54,9 +54,11 @@
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
#include "graphics/font.h"
|
#include "graphics/font.h"
|
||||||
#include "backends/timer/default/default-timer.h"
|
#include "backends/timer/default/default-timer.h"
|
||||||
#include "sound/mixer.h"
|
#include "sound/mixer_intern.h"
|
||||||
#include "common/events.h"
|
#include "common/events.h"
|
||||||
#include "backends/platform/ps2/ps2debug.h"
|
#include "backends/platform/ps2/ps2debug.h"
|
||||||
|
#include "backends/fs/ps2/ps2-fs-factory.h"
|
||||||
|
|
||||||
// asm("mfc0 %0, $9\n" : "=r"(tickStart));
|
// asm("mfc0 %0, $9\n" : "=r"(tickStart));
|
||||||
|
|
||||||
extern void *_gp;
|
extern void *_gp;
|
||||||
|
@ -309,7 +311,9 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) {
|
||||||
void OSystem_PS2::init(void) {
|
void OSystem_PS2::init(void) {
|
||||||
sioprintf("Timer...\n");
|
sioprintf("Timer...\n");
|
||||||
_scummTimerManager = new DefaultTimerManager();
|
_scummTimerManager = new DefaultTimerManager();
|
||||||
_scummMixer = new Audio::Mixer();
|
_scummMixer = new Audio::MixerImpl(this);
|
||||||
|
_scummMixer->setOutputRate(44100);
|
||||||
|
_scummMixer->setReady(true);
|
||||||
initTimer();
|
initTimer();
|
||||||
|
|
||||||
sioprintf("Starting SavefileManager\n");
|
sioprintf("Starting SavefileManager\n");
|
||||||
|
@ -410,7 +414,8 @@ void OSystem_PS2::soundThread(void) {
|
||||||
// we have to produce more samples, call sound mixer
|
// we have to produce more samples, call sound mixer
|
||||||
// the scratchpad at 0x70000000 is used as temporary soundbuffer
|
// the scratchpad at 0x70000000 is used as temporary soundbuffer
|
||||||
//_scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
|
//_scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
|
||||||
Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
|
// Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
|
||||||
|
_scummMixer->mixCallback((byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
|
||||||
|
|
||||||
// demux data into 2 buffers, L and R
|
// demux data into 2 buffers, L and R
|
||||||
__asm__ (
|
__asm__ (
|
||||||
|
@ -534,10 +539,6 @@ Common::TimerManager *OSystem_PS2::getTimerManager() {
|
||||||
return _scummTimerManager;
|
return _scummTimerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OSystem_PS2::getOutputSampleRate(void) const {
|
|
||||||
return 48000;
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio::Mixer *OSystem_PS2::getMixer() {
|
Audio::Mixer *OSystem_PS2::getMixer() {
|
||||||
return _scummMixer;
|
return _scummMixer;
|
||||||
}
|
}
|
||||||
|
@ -546,6 +547,10 @@ Common::SaveFileManager *OSystem_PS2::getSavefileManager(void) {
|
||||||
return _saveManager;
|
return _saveManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilesystemFactory *OSystem_PS2::getFilesystemFactory() {
|
||||||
|
return &Ps2FilesystemFactory::instance();
|
||||||
|
}
|
||||||
|
|
||||||
void OSystem_PS2::setShakePos(int shakeOffset) {
|
void OSystem_PS2::setShakePos(int shakeOffset) {
|
||||||
_screen->setShakePos(shakeOffset);
|
_screen->setShakePos(shakeOffset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class DefaultTimerManager;
|
||||||
class Gs2dScreen;
|
class Gs2dScreen;
|
||||||
class Ps2Input;
|
class Ps2Input;
|
||||||
class Ps2SaveFileManager;
|
class Ps2SaveFileManager;
|
||||||
|
// class Ps2FilesystemFactory;
|
||||||
struct IrxReference;
|
struct IrxReference;
|
||||||
|
|
||||||
#define MAX_MUTEXES 16
|
#define MAX_MUTEXES 16
|
||||||
|
@ -48,7 +49,7 @@ namespace Common {
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
class Mixer;
|
class MixerImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OSystem_PS2 : public OSystem {
|
class OSystem_PS2 : public OSystem {
|
||||||
|
@ -87,7 +88,6 @@ public:
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
|
||||||
virtual Audio::Mixer *getMixer();
|
virtual Audio::Mixer *getMixer();
|
||||||
virtual int getOutputSampleRate(void) const;
|
|
||||||
|
|
||||||
virtual bool openCD(int drive);
|
virtual bool openCD(int drive);
|
||||||
virtual bool pollCD();
|
virtual bool pollCD();
|
||||||
|
@ -112,6 +112,7 @@ public:
|
||||||
virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
|
virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
|
||||||
|
|
||||||
virtual Common::SaveFileManager *getSavefileManager();
|
virtual Common::SaveFileManager *getSavefileManager();
|
||||||
|
virtual FilesystemFactory *getFilesystemFactory();
|
||||||
|
|
||||||
virtual void getTimeAndDate(struct tm &t) const;
|
virtual void getTimeAndDate(struct tm &t) const;
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ private:
|
||||||
void readRtcTime(void);
|
void readRtcTime(void);
|
||||||
|
|
||||||
DefaultTimerManager *_scummTimerManager;
|
DefaultTimerManager *_scummTimerManager;
|
||||||
Audio::Mixer *_scummMixer;
|
Audio::MixerImpl *_scummMixer;
|
||||||
|
|
||||||
|
|
||||||
bool _mouseVisible;
|
bool _mouseVisible;
|
||||||
|
|
|
@ -191,7 +191,7 @@ OSystem_SDL::OSystem_SDL()
|
||||||
|
|
||||||
OSystem_SDL::~OSystem_SDL() {
|
OSystem_SDL::~OSystem_SDL() {
|
||||||
SDL_RemoveTimer(_timerID);
|
SDL_RemoveTimer(_timerID);
|
||||||
SDL_CloseAudio();
|
closeMixer();
|
||||||
|
|
||||||
free(_dirtyChecksums);
|
free(_dirtyChecksums);
|
||||||
free(_currentPalette);
|
free(_currentPalette);
|
||||||
|
@ -199,7 +199,6 @@ OSystem_SDL::~OSystem_SDL() {
|
||||||
free(_mouseData);
|
free(_mouseData);
|
||||||
|
|
||||||
delete _savefile;
|
delete _savefile;
|
||||||
delete _mixer;
|
|
||||||
delete _timer;
|
delete _timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +305,7 @@ void OSystem_SDL::quit() {
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
|
||||||
SDL_RemoveTimer(_timerID);
|
SDL_RemoveTimer(_timerID);
|
||||||
SDL_CloseAudio();
|
closeMixer();
|
||||||
|
|
||||||
free(_dirtyChecksums);
|
free(_dirtyChecksums);
|
||||||
free(_currentPalette);
|
free(_currentPalette);
|
||||||
|
@ -314,7 +313,6 @@ void OSystem_SDL::quit() {
|
||||||
free(_mouseData);
|
free(_mouseData);
|
||||||
|
|
||||||
delete _savefile;
|
delete _savefile;
|
||||||
delete _mixer;
|
|
||||||
delete _timer;
|
delete _timer;
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
@ -389,14 +387,110 @@ void OSystem_SDL::deleteMutex(MutexRef mutex) {
|
||||||
#pragma mark --- Audio ---
|
#pragma mark --- Audio ---
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
|
#ifdef MIXER_DOUBLE_BUFFERING
|
||||||
|
|
||||||
|
void OSystem_SDL::mixerProducerThread() {
|
||||||
|
byte nextSoundBuffer;
|
||||||
|
|
||||||
|
SDL_LockMutex(_soundMutex);
|
||||||
|
while (true) {
|
||||||
|
// Wait till we are allowed to produce data
|
||||||
|
SDL_CondWait(_soundCond, _soundMutex);
|
||||||
|
|
||||||
|
if (_soundThreadShouldQuit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Generate samples and put them into the next buffer
|
||||||
|
nextSoundBuffer = _activeSoundBuf ^ 1;
|
||||||
|
_mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize);
|
||||||
|
|
||||||
|
// Swap buffers
|
||||||
|
_activeSoundBuf = nextSoundBuffer;
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(_soundMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDLCALL OSystem_SDL::mixerProducerThreadEntry(void *arg) {
|
||||||
|
OSystem_SDL *this_ = (OSystem_SDL *)arg;
|
||||||
|
assert(this_);
|
||||||
|
this_->mixerProducerThread();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OSystem_SDL::initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize) {
|
||||||
|
_soundThreadIsRunning = false;
|
||||||
|
_soundThreadShouldQuit = false;
|
||||||
|
|
||||||
|
// Create mutex and condition variable
|
||||||
|
_soundMutex = SDL_CreateMutex();
|
||||||
|
_soundCond = SDL_CreateCond();
|
||||||
|
|
||||||
|
// Create two sound buffers
|
||||||
|
_activeSoundBuf = 0;
|
||||||
|
_soundBufSize = bufSize;
|
||||||
|
_soundBuffers[0] = (byte *)calloc(1, bufSize);
|
||||||
|
_soundBuffers[1] = (byte *)calloc(1, bufSize);
|
||||||
|
|
||||||
|
_soundThreadIsRunning = true;
|
||||||
|
|
||||||
|
// Finally start the thread
|
||||||
|
_soundThread = SDL_CreateThread(mixerProducerThreadEntry, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_SDL::deinitThreadedMixer() {
|
||||||
|
// Kill thread?? _soundThread
|
||||||
|
|
||||||
|
if (_soundThreadIsRunning) {
|
||||||
|
// Signal the producer thread to end, and wait for it to actually finish.
|
||||||
|
_soundThreadShouldQuit = true;
|
||||||
|
SDL_CondBroadcast(_soundCond);
|
||||||
|
SDL_WaitThread(_soundThread, NULL);
|
||||||
|
|
||||||
|
// Kill the mutex & cond variables.
|
||||||
|
// Attention: AT this point, the mixer callback must not be running
|
||||||
|
// anymore, else we will crash!
|
||||||
|
SDL_DestroyMutex(_soundMutex);
|
||||||
|
SDL_DestroyCond(_soundCond);
|
||||||
|
|
||||||
|
_soundThreadIsRunning = false;
|
||||||
|
|
||||||
|
free(_soundBuffers[0]);
|
||||||
|
free(_soundBuffers[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OSystem_SDL::mixCallback(void *arg, byte *samples, int len) {
|
||||||
|
OSystem_SDL *this_ = (OSystem_SDL *)arg;
|
||||||
|
assert(this_);
|
||||||
|
assert(this_->_mixer);
|
||||||
|
|
||||||
|
assert((int)this_->_soundBufSize == len);
|
||||||
|
|
||||||
|
// Lock mutex, to ensure our data is not overwritten by the producer thread
|
||||||
|
SDL_LockMutex(this_->_soundMutex);
|
||||||
|
|
||||||
|
// Copy data from the current sound buffer
|
||||||
|
memcpy(samples, this_->_soundBuffers[this_->_activeSoundBuf], len);
|
||||||
|
|
||||||
|
// Unlock mutex and wake up the produced thread
|
||||||
|
SDL_UnlockMutex(this_->_soundMutex);
|
||||||
|
SDL_CondSignal(this_->_soundCond);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) {
|
void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) {
|
||||||
OSystem_SDL *this_ = (OSystem_SDL *)sys;
|
OSystem_SDL *this_ = (OSystem_SDL *)sys;
|
||||||
assert(this_);
|
assert(this_);
|
||||||
|
assert(this_->_mixer);
|
||||||
|
|
||||||
if (this_->_mixer)
|
this_->_mixer->mixCallback(samples, len);
|
||||||
this_->_mixer->mixCallback(samples, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void OSystem_SDL::setupMixer() {
|
void OSystem_SDL::setupMixer() {
|
||||||
SDL_AudioSpec desired;
|
SDL_AudioSpec desired;
|
||||||
SDL_AudioSpec obtained;
|
SDL_AudioSpec obtained;
|
||||||
|
@ -443,10 +537,31 @@ void OSystem_SDL::setupMixer() {
|
||||||
// Tell the mixer that we are ready and start the sound processing
|
// Tell the mixer that we are ready and start the sound processing
|
||||||
_mixer->setOutputRate(_samplesPerSec);
|
_mixer->setOutputRate(_samplesPerSec);
|
||||||
_mixer->setReady(true);
|
_mixer->setReady(true);
|
||||||
|
|
||||||
|
#ifdef MIXER_DOUBLE_BUFFERING
|
||||||
|
initThreadedMixer(_mixer, obtained.samples * 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// start the sound system
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSystem_SDL::closeMixer() {
|
||||||
|
if (_mixer)
|
||||||
|
_mixer->setReady(false);
|
||||||
|
|
||||||
|
SDL_CloseAudio();
|
||||||
|
|
||||||
|
delete _mixer;
|
||||||
|
_mixer = 0;
|
||||||
|
|
||||||
|
#ifdef MIXER_DOUBLE_BUFFERING
|
||||||
|
deinitThreadedMixer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Audio::Mixer *OSystem_SDL::getMixer() {
|
Audio::Mixer *OSystem_SDL::getMixer() {
|
||||||
assert(_mixer);
|
assert(_mixer);
|
||||||
return _mixer;
|
return _mixer;
|
||||||
|
|
|
@ -51,6 +51,15 @@ namespace Common {
|
||||||
#define USE_OSD 1
|
#define USE_OSD 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MACOSX)
|
||||||
|
// On Mac OS X, we need to double buffer the audio buffer, else anything
|
||||||
|
// which produces sampled data with high latency (like the MT-32 emulator)
|
||||||
|
// will sound terribly.
|
||||||
|
// This could be enabled for more / most ports in the future, but needs some
|
||||||
|
// testing.
|
||||||
|
#define MIXER_DOUBLE_BUFFERING 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GFX_NORMAL = 0,
|
GFX_NORMAL = 0,
|
||||||
|
@ -137,6 +146,8 @@ public:
|
||||||
virtual void setupMixer();
|
virtual void setupMixer();
|
||||||
static void mixCallback(void *s, byte *samples, int len);
|
static void mixCallback(void *s, byte *samples, int len);
|
||||||
|
|
||||||
|
virtual void closeMixer();
|
||||||
|
|
||||||
virtual Audio::Mixer *getMixer();
|
virtual Audio::Mixer *getMixer();
|
||||||
|
|
||||||
// Poll CD status
|
// Poll CD status
|
||||||
|
@ -369,6 +380,23 @@ protected:
|
||||||
*/
|
*/
|
||||||
MutexRef _graphicsMutex;
|
MutexRef _graphicsMutex;
|
||||||
|
|
||||||
|
#ifdef MIXER_DOUBLE_BUFFERING
|
||||||
|
SDL_mutex *_soundMutex;
|
||||||
|
SDL_cond *_soundCond;
|
||||||
|
SDL_Thread *_soundThread;
|
||||||
|
bool _soundThreadIsRunning;
|
||||||
|
bool _soundThreadShouldQuit;
|
||||||
|
|
||||||
|
byte _activeSoundBuf;
|
||||||
|
uint _soundBufSize;
|
||||||
|
byte *_soundBuffers[2];
|
||||||
|
|
||||||
|
void mixerProducerThread();
|
||||||
|
static int SDLCALL mixerProducerThreadEntry(void *arg);
|
||||||
|
void initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize);
|
||||||
|
void deinitThreadedMixer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Common::SaveFileManager *_savefile;
|
Common::SaveFileManager *_savefile;
|
||||||
Audio::MixerImpl *_mixer;
|
Audio::MixerImpl *_mixer;
|
||||||
|
@ -377,7 +405,7 @@ protected:
|
||||||
Common::TimerManager *_timer;
|
Common::TimerManager *_timer;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
void addDirtyRgnAuto(const byte *buf);
|
void addDirtyRgnAuto(const byte *buf);
|
||||||
void makeChecksums(const byte *buf);
|
void makeChecksums(const byte *buf);
|
||||||
|
|
||||||
|
|
|
@ -226,28 +226,31 @@
|
||||||
$VariationSets{'ALL'}{'all'} = "$DefaultFeatures @WorkingEngines @EnablableSubEngines";
|
$VariationSets{'ALL'}{'all'} = "$DefaultFeatures @WorkingEngines @EnablableSubEngines";
|
||||||
|
|
||||||
# now one for each ready-for-release engine
|
# now one for each ready-for-release engine
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
foreach (@WorkingEngines)
|
foreach (@WorkingEngines)
|
||||||
{
|
{
|
||||||
$VariationSets{'ALL'}{$_} = "$DefaultFeatures $_";
|
$VariationSets{'ALL'}{$_} = "$DefaultFeatures $_";
|
||||||
}
|
}
|
||||||
# for scumm, we need to add 2 features:
|
# for scumm, we need to add 2 features:
|
||||||
$VariationSets{'ALL'}{'scumm'} .= " scumm_7_8 he";
|
#$VariationSets{'ALL'}{'scumm'} .= " scumm_7_8 he";
|
||||||
|
}
|
||||||
|
|
||||||
# now one for each not-ready-for-release-or-testing engine
|
# now one for each not-ready-for-release-or-testing engine
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
foreach (@TestingEngines)
|
foreach (@TestingEngines)
|
||||||
{
|
{
|
||||||
$VariationSets{'ALL'}{"test_$_"} = "$DefaultFeatures $_";
|
$VariationSets{'ALL'}{"test_$_"} = "$DefaultFeatures $_";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
# below here you could specify weird & experimental combinations, non-ready engines
|
# below here you could specify weird & experimental combinations, non-ready engines
|
||||||
|
|
||||||
# a small version of the saga engine, because it is so big (no tremor,mad,zlib)
|
# a small version of the saga engine, because it is so big (no tremor,mad,zlib)
|
||||||
$VariationSets{'ALL'}{'saga_mini'} = "saga";
|
#$VariationSets{'ALL'}{'saga_mini'} = "saga";
|
||||||
|
|
||||||
# a smaller version of scumm without support for v7, v8 and HE games
|
# a smaller version of scumm without support for v7, v8 and HE games
|
||||||
$VariationSets{'ALL'}{'scumm_no78he'} = "$DefaultFeatures scumm";
|
#$VariationSets{'ALL'}{'scumm_no78he'} = "$DefaultFeatures scumm";
|
||||||
|
|
||||||
# maybe you feel lucky and want to test the sword engines? :P
|
# maybe you feel lucky and want to test the sword engines? :P
|
||||||
#$VariationSets{'S60v2'}{'test_sword'} = "$DefaultFeatures mpeg2 sword1 sword2";
|
#$VariationSets{'S60v2'}{'test_sword'} = "$DefaultFeatures mpeg2 sword1 sword2";
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "gui/Actions.h"
|
#include "gui/Actions.h"
|
||||||
#include "gui/Key.h"
|
#include "gui/Key.h"
|
||||||
#include "gui/message.h"
|
#include "gui/message.h"
|
||||||
|
#include "sound/mixer_intern.h"
|
||||||
#include "..\..\sdl\main.cpp"
|
#include "..\..\sdl\main.cpp"
|
||||||
|
|
||||||
#ifdef SAMPLES_PER_SEC_8000 // the GreanSymbianMMP format cannot handle values for defines :(
|
#ifdef SAMPLES_PER_SEC_8000 // the GreanSymbianMMP format cannot handle values for defines :(
|
||||||
|
@ -42,10 +42,22 @@
|
||||||
#define SAMPLES_PER_SEC 16000
|
#define SAMPLES_PER_SEC 16000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define KInputBufferLength 128
|
||||||
|
// Symbian libc file functionality in order to provide shared file handles
|
||||||
|
struct TSymbianFileEntry {
|
||||||
|
RFile iFileHandle;
|
||||||
|
char iInputBuffer[KInputBufferLength];
|
||||||
|
TInt iInputBufferLen;
|
||||||
|
TInt iInputPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FILE void
|
||||||
|
|
||||||
////////// extern "C" ///////////////////////////////////////////////////
|
////////// extern "C" ///////////////////////////////////////////////////
|
||||||
namespace Symbian {
|
namespace Symbian {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Show a simple Symbian Info win with Msg & exit
|
// Show a simple Symbian Info win with Msg & exit
|
||||||
void FatalError(const char *msg) {
|
void FatalError(const char *msg) {
|
||||||
TPtrC8 msgPtr((const TUint8 *)msg);
|
TPtrC8 msgPtr((const TUint8 *)msg);
|
||||||
|
@ -246,9 +258,9 @@ void OSystem_SDL_Symbian::symbianMixCallback(void *sys, byte *samples, int len)
|
||||||
if (!this_->_mixer)
|
if (!this_->_mixer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef S60
|
#if defined (S60) && !defined(S60V3)
|
||||||
// If not stereo then we need to downmix
|
// If not stereo then we need to downmix
|
||||||
if (_channels != 2) {
|
if (this_->_mixer->_channels != 2) {
|
||||||
this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2);
|
this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2);
|
||||||
|
|
||||||
int16 *bitmixDst = (int16 *)samples;
|
int16 *bitmixDst = (int16 *)samples;
|
||||||
|
@ -443,15 +455,9 @@ void OSystem_SDL_Symbian::initZones() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symbian libc file functionality in order to provide shared file handles
|
|
||||||
struct TSymbianFileEntry {
|
|
||||||
RFile iFileHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FILE void
|
|
||||||
|
|
||||||
FILE* symbian_fopen(const char* name, const char* mode) {
|
FILE* symbian_fopen(const char* name, const char* mode) {
|
||||||
TSymbianFileEntry* fileEntry = new TSymbianFileEntry;
|
TSymbianFileEntry* fileEntry = new TSymbianFileEntry;
|
||||||
|
fileEntry->iInputPos = KErrNotFound;
|
||||||
|
|
||||||
if (fileEntry != NULL) {
|
if (fileEntry != NULL) {
|
||||||
TInt modeLen = strlen(mode);
|
TInt modeLen = strlen(mode);
|
||||||
|
@ -509,9 +515,71 @@ void symbian_fclose(FILE* handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t symbian_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
size_t symbian_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
||||||
TPtr8 pointer( (unsigned char*) ptr, size*numItems);
|
TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
|
||||||
|
TUint32 totsize = size*numItems;
|
||||||
|
TPtr8 pointer ( (unsigned char*) ptr, totsize);
|
||||||
|
|
||||||
((TSymbianFileEntry*)(handle))->iFileHandle.Read(pointer);
|
// Nothing cached and we want to load at least KInputBufferLength bytes
|
||||||
|
if(totsize >= KInputBufferLength) {
|
||||||
|
TUint32 totLength = 0;
|
||||||
|
if(entry->iInputPos != KErrNotFound)
|
||||||
|
{
|
||||||
|
TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer+entry->iInputPos, entry->iInputBufferLen - entry->iInputPos, KInputBufferLength);
|
||||||
|
pointer.Append(cacheBuffer);
|
||||||
|
entry->iInputPos = KErrNotFound;
|
||||||
|
totLength+=pointer.Length();
|
||||||
|
pointer.Set(totLength+(unsigned char*) ptr, 0, totsize-totLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->iFileHandle.Read(pointer);
|
||||||
|
totLength+=pointer.Length();
|
||||||
|
|
||||||
|
pointer.Set((unsigned char*) ptr, totLength, totsize);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Nothing in buffer
|
||||||
|
if(entry->iInputPos == KErrNotFound) {
|
||||||
|
TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer, KInputBufferLength);
|
||||||
|
entry->iFileHandle.Read(cacheBuffer);
|
||||||
|
|
||||||
|
if(cacheBuffer.Length() >= totsize) {
|
||||||
|
pointer.Copy(cacheBuffer.Left(totsize));
|
||||||
|
entry->iInputPos = totsize;
|
||||||
|
entry->iInputBufferLen = cacheBuffer.Length();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pointer.Copy(cacheBuffer);
|
||||||
|
entry->iInputPos = KErrNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer, entry->iInputBufferLen, KInputBufferLength);
|
||||||
|
|
||||||
|
if(entry->iInputPos+totsize < entry->iInputBufferLen) {
|
||||||
|
pointer.Copy(cacheBuffer.Mid(entry->iInputPos, totsize));
|
||||||
|
entry->iInputPos+=totsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
pointer.Copy(cacheBuffer.Mid(entry->iInputPos, entry->iInputBufferLen-entry->iInputPos));
|
||||||
|
cacheBuffer.SetLength(0);
|
||||||
|
entry->iFileHandle.Read(cacheBuffer);
|
||||||
|
|
||||||
|
if(cacheBuffer.Length() >= totsize-pointer.Length()) {
|
||||||
|
TUint32 restSize = totsize-pointer.Length();
|
||||||
|
pointer.Append(cacheBuffer.Left(restSize));
|
||||||
|
entry->iInputPos = restSize;
|
||||||
|
entry->iInputBufferLen = cacheBuffer.Length();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pointer.Append(cacheBuffer);
|
||||||
|
entry->iInputPos = KErrNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pointer.Length()/size;
|
return pointer.Length()/size;
|
||||||
}
|
}
|
||||||
|
@ -519,6 +587,7 @@ size_t symbian_fread(const void* ptr, size_t size, size_t numItems, FILE* handle
|
||||||
size_t symbian_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
size_t symbian_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
||||||
TPtrC8 pointer( (unsigned char*) ptr, size*numItems);
|
TPtrC8 pointer( (unsigned char*) ptr, size*numItems);
|
||||||
|
|
||||||
|
((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;
|
||||||
if (((TSymbianFileEntry*)(handle))->iFileHandle.Write(pointer) == KErrNone) {
|
if (((TSymbianFileEntry*)(handle))->iFileHandle.Write(pointer) == KErrNone) {
|
||||||
return numItems;
|
return numItems;
|
||||||
}
|
}
|
||||||
|
@ -528,12 +597,18 @@ size_t symbian_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handl
|
||||||
|
|
||||||
bool symbian_feof(FILE* handle) {
|
bool symbian_feof(FILE* handle) {
|
||||||
TInt pos = 0;
|
TInt pos = 0;
|
||||||
if (((TSymbianFileEntry*)(handle))->iFileHandle.Seek(ESeekCurrent, pos) == KErrNone) {
|
TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
|
||||||
|
|
||||||
|
if (entry->iFileHandle.Seek(ESeekCurrent, pos) == KErrNone) {
|
||||||
|
|
||||||
TInt size = 0;
|
TInt size = 0;
|
||||||
if (((TSymbianFileEntry*)(handle))->iFileHandle.Size(size) == KErrNone) {
|
if (entry->iFileHandle.Size(size) == KErrNone) {
|
||||||
if (pos == size)
|
if(entry->iInputPos == KErrNotFound && pos == size)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if(entry->iInputPos != KErrNotFound && pos == size && entry->iInputPos == entry->iInputBufferLen)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,6 +624,7 @@ long int symbian_ftell(FILE* handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int symbian_fseek(FILE* handle, long int offset, int whence) {
|
int symbian_fseek(FILE* handle, long int offset, int whence) {
|
||||||
|
|
||||||
TSeek seekMode = ESeekStart;
|
TSeek seekMode = ESeekStart;
|
||||||
TInt pos = offset;
|
TInt pos = offset;
|
||||||
|
|
||||||
|
@ -564,6 +640,8 @@ int symbian_fseek(FILE* handle, long int offset, int whence) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;
|
||||||
|
|
||||||
return ((TSymbianFileEntry*)(handle))->iFileHandle.Seek(seekMode, pos);
|
return ((TSymbianFileEntry*)(handle))->iFileHandle.Seek(seekMode, pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,34 @@
|
||||||
/* MISSING.C
|
/* ScummVM - Graphic Adventure Engine
|
||||||
Implementation for standard and semi-standard C library calls missing in WinCE
|
*
|
||||||
environment.
|
* ScummVM is the legal property of its developers, whose names
|
||||||
by Vasyl Tsvirkunov
|
* 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.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Original code:
|
||||||
|
* Implementation for standard and semi-standard C library calls missing in WinCE
|
||||||
|
* environment.
|
||||||
|
* by Vasyl Tsvirkunov
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
@ -17,19 +43,8 @@
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "dirent.h"
|
#include "dirent.h"
|
||||||
|
|
||||||
/* forward declaration */
|
|
||||||
|
|
||||||
#if _WIN32_WCE < 300
|
|
||||||
|
|
||||||
#define _STDAFX_H
|
|
||||||
#include "portdefs.h"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
char *strdup(const char *strSource);
|
char *strdup(const char *strSource);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define EXT_C extern "C"
|
#define EXT_C extern "C"
|
||||||
#else
|
#else
|
||||||
|
@ -40,19 +55,27 @@ char *strdup(const char *strSource);
|
||||||
|
|
||||||
void *bsearch(const void *key, const void *base, size_t nmemb,
|
void *bsearch(const void *key, const void *base, size_t nmemb,
|
||||||
size_t size, int (*compar)(const void *, const void *)) {
|
size_t size, int (*compar)(const void *, const void *)) {
|
||||||
size_t i;
|
// Perform binary search
|
||||||
|
size_t lo = 0;
|
||||||
|
size_t hi = nmemb;
|
||||||
|
while (lo < hi) {
|
||||||
|
size_t mid = (lo + hi) / 2;
|
||||||
|
const void *p = ((const char *)base) + mid * size;
|
||||||
|
int tmp = (*compar)(key, p);
|
||||||
|
if (tmp < 0)
|
||||||
|
hi = mid;
|
||||||
|
else if (tmp > 0)
|
||||||
|
lo = mid + 1;
|
||||||
|
else
|
||||||
|
return (void *)p;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<nmemb; i++)
|
|
||||||
if (compar(key, (void*)((size_t)base + size * i)) == 0)
|
|
||||||
return (void*)((size_t)base + size * i);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WIN32_FIND_DATA wfd;
|
static WIN32_FIND_DATA wfd;
|
||||||
|
|
||||||
/* Very limited implementation of stat. Used by UI.C, MEMORY-P.C (latter is not critical) */
|
int stat(const char *fname, struct stat *ss) {
|
||||||
int stat(const char *fname, struct stat *ss)
|
|
||||||
{
|
|
||||||
TCHAR fnameUnc[MAX_PATH+1];
|
TCHAR fnameUnc[MAX_PATH+1];
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
int len;
|
int len;
|
||||||
|
@ -63,8 +86,7 @@ int stat(const char *fname, struct stat *ss)
|
||||||
/* Special case (dummy on WinCE) */
|
/* Special case (dummy on WinCE) */
|
||||||
len = strlen(fname);
|
len = strlen(fname);
|
||||||
if (len >= 2 && fname[len-1] == '.' && fname[len-2] == '.' &&
|
if (len >= 2 && fname[len-1] == '.' && fname[len-2] == '.' &&
|
||||||
(len == 2 || fname[len-3] == '\\'))
|
(len == 2 || fname[len-3] == '\\')) {
|
||||||
{
|
|
||||||
/* That's everything implemented so far */
|
/* That's everything implemented so far */
|
||||||
memset(ss, 0, sizeof(struct stat));
|
memset(ss, 0, sizeof(struct stat));
|
||||||
ss->st_size = 1024;
|
ss->st_size = 1024;
|
||||||
|
@ -74,6 +96,7 @@ int stat(const char *fname, struct stat *ss)
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameUnc, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameUnc, MAX_PATH);
|
||||||
handle = FindFirstFile(fnameUnc, &wfd);
|
handle = FindFirstFile(fnameUnc, &wfd);
|
||||||
|
FindClose(handle);
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
|
@ -83,20 +106,16 @@ int stat(const char *fname, struct stat *ss)
|
||||||
ss->st_size = wfd.nFileSizeLow;
|
ss->st_size = wfd.nFileSizeLow;
|
||||||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
ss->st_mode |= S_IFDIR;
|
ss->st_mode |= S_IFDIR;
|
||||||
|
|
||||||
FindClose(handle);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char cwd[MAX_PATH+1] = "";
|
char cwd[MAX_PATH+1] = "";
|
||||||
EXT_C char *getcwd(char *buffer, int maxlen)
|
EXT_C char *getcwd(char *buffer, int maxlen) {
|
||||||
{
|
|
||||||
TCHAR fileUnc[MAX_PATH+1];
|
TCHAR fileUnc[MAX_PATH+1];
|
||||||
char* plast;
|
char* plast;
|
||||||
|
|
||||||
if (cwd[0] == 0)
|
if (cwd[0] == 0) {
|
||||||
{
|
|
||||||
GetModuleFileName(NULL, fileUnc, MAX_PATH);
|
GetModuleFileName(NULL, fileUnc, MAX_PATH);
|
||||||
WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
|
||||||
plast = strrchr(cwd, '\\');
|
plast = strrchr(cwd, '\\');
|
||||||
|
@ -114,8 +133,7 @@ EXT_C char *getcwd(char *buffer, int maxlen)
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#undef GetCurrentDirectory
|
#undef GetCurrentDirectory
|
||||||
#endif
|
#endif
|
||||||
EXT_C void GetCurrentDirectory(int len, char *buf)
|
EXT_C void GetCurrentDirectory(int len, char *buf) {
|
||||||
{
|
|
||||||
getcwd(buf,len);
|
getcwd(buf,len);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,26 +143,22 @@ fully qualified paths refer to root folder rather
|
||||||
than current folder (concept not implemented in CE).
|
than current folder (concept not implemented in CE).
|
||||||
*/
|
*/
|
||||||
#undef fopen
|
#undef fopen
|
||||||
EXT_C FILE *wce_fopen(const char* fname, const char* fmode)
|
EXT_C FILE *wce_fopen(const char* fname, const char* fmode) {
|
||||||
{
|
|
||||||
char fullname[MAX_PATH+1];
|
char fullname[MAX_PATH+1];
|
||||||
|
|
||||||
if (!fname || fname[0] == '\0')
|
if (!fname || fname[0] == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
if (fname[0] != '\\' && fname[0] != '/')
|
if (fname[0] != '\\' && fname[0] != '/') {
|
||||||
{
|
|
||||||
getcwd(fullname, MAX_PATH);
|
getcwd(fullname, MAX_PATH);
|
||||||
strncat(fullname, "\\", MAX_PATH-strlen(fullname)-1);
|
strncat(fullname, "\\", MAX_PATH-strlen(fullname)-1);
|
||||||
strncat(fullname, fname, MAX_PATH-strlen(fullname)-strlen(fname));
|
strncat(fullname, fname, MAX_PATH-strlen(fullname)-strlen(fname));
|
||||||
return fopen(fullname, fmode);
|
return fopen(fullname, fmode);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return fopen(fname, fmode);
|
return fopen(fname, fmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove file by name */
|
/* Remove file by name */
|
||||||
int remove(const char* path)
|
int remove(const char* path) {
|
||||||
{
|
|
||||||
TCHAR pathUnc[MAX_PATH+1];
|
TCHAR pathUnc[MAX_PATH+1];
|
||||||
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
|
||||||
return !DeleteFile(pathUnc);
|
return !DeleteFile(pathUnc);
|
||||||
|
@ -158,14 +172,22 @@ int _access(const char *path, int mode) {
|
||||||
|
|
||||||
WIN32_FIND_DATA ffd;
|
WIN32_FIND_DATA ffd;
|
||||||
HANDLE h=FindFirstFile(fname, &ffd);
|
HANDLE h=FindFirstFile(fname, &ffd);
|
||||||
|
FindClose(h);
|
||||||
|
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
return -1; //Can't find file
|
return -1; //Can't find file
|
||||||
FindClose(h);
|
|
||||||
|
|
||||||
if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// WORKAROUND: WinCE (or the emulator) sometimes returns bogus direcotry
|
||||||
|
// hits for files that don't exist. Checking for the same fname twice
|
||||||
|
// seems to weed out those false positives.
|
||||||
|
HANDLE h=FindFirstFile(fname, &ffd);
|
||||||
|
FindClose(h);
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
return -1; //Can't find file
|
||||||
|
|
||||||
return 0; //Always return success if target is directory and exists
|
return 0; //Always return success if target is directory and exists
|
||||||
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 00: //Check existence
|
case 00: //Check existence
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -183,8 +205,7 @@ int _access(const char *path, int mode) {
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
|
|
||||||
/* Limited dirent implementation. Used by UI.C and DEVICES.C */
|
/* Limited dirent implementation. Used by UI.C and DEVICES.C */
|
||||||
DIR* opendir(const char* fname)
|
DIR* opendir(const char* fname) {
|
||||||
{
|
|
||||||
DIR* pdir;
|
DIR* pdir;
|
||||||
char fnameMask[MAX_PATH+1];
|
char fnameMask[MAX_PATH+1];
|
||||||
TCHAR fnameUnc[MAX_PATH+1];
|
TCHAR fnameUnc[MAX_PATH+1];
|
||||||
|
@ -209,13 +230,10 @@ DIR* opendir(const char* fname)
|
||||||
strcpy(pdir->dd_name, fname); /* it has exactly enough space for fname and nul char */
|
strcpy(pdir->dd_name, fname); /* it has exactly enough space for fname and nul char */
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, fnameMask, -1, fnameUnc, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, fnameMask, -1, fnameUnc, MAX_PATH);
|
||||||
if ((pdir->dd_handle = (long)FindFirstFile(fnameUnc, &wfd)) == (long)INVALID_HANDLE_VALUE)
|
if ((pdir->dd_handle = (long)FindFirstFile(fnameUnc, &wfd)) == (long)INVALID_HANDLE_VALUE) {
|
||||||
{
|
|
||||||
free(pdir);
|
free(pdir);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
|
||||||
|
|
||||||
pdir->dd_dir.d_name = strdup(nameFound);
|
pdir->dd_dir.d_name = strdup(nameFound);
|
||||||
|
@ -224,34 +242,25 @@ DIR* opendir(const char* fname)
|
||||||
return pdir;
|
return pdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent* readdir(DIR* dir)
|
struct dirent* readdir(DIR* dir) {
|
||||||
{
|
|
||||||
char nameFound[MAX_PATH+1];
|
char nameFound[MAX_PATH+1];
|
||||||
static struct dirent dummy;
|
static struct dirent dummy;
|
||||||
|
|
||||||
if (dir->dd_stat == 0)
|
if (dir->dd_stat == 0) {
|
||||||
{
|
|
||||||
dummy.d_name = ".";
|
dummy.d_name = ".";
|
||||||
dummy.d_namlen = 1;
|
dummy.d_namlen = 1;
|
||||||
dir->dd_stat ++;
|
dir->dd_stat ++;
|
||||||
return &dummy;
|
return &dummy;
|
||||||
}
|
} else if (dir->dd_stat == 1) {
|
||||||
else if (dir->dd_stat == 1)
|
|
||||||
{
|
|
||||||
dummy.d_name = "..";
|
dummy.d_name = "..";
|
||||||
dummy.d_namlen = 2;
|
dummy.d_namlen = 2;
|
||||||
dir->dd_stat ++;
|
dir->dd_stat ++;
|
||||||
return &dummy;
|
return &dummy;
|
||||||
}
|
} else if (dir->dd_stat == 2) {
|
||||||
else if (dir->dd_stat == 2)
|
|
||||||
{
|
|
||||||
dir->dd_stat++;
|
dir->dd_stat++;
|
||||||
return &dir->dd_dir;
|
return &dir->dd_dir;
|
||||||
}
|
} else {
|
||||||
else
|
if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0) {
|
||||||
{
|
|
||||||
if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0)
|
|
||||||
{
|
|
||||||
dir->dd_stat = -1;
|
dir->dd_stat = -1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -283,12 +292,6 @@ int closedir(DIR* dir)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in our case unlink is the same as remove */
|
|
||||||
int unlink(const char* path)
|
|
||||||
{
|
|
||||||
return remove(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make directory, Unix style */
|
/* Make directory, Unix style */
|
||||||
void mkdir(char* dirname, int mode)
|
void mkdir(char* dirname, int mode)
|
||||||
{
|
{
|
||||||
|
@ -299,10 +302,8 @@ void mkdir(char* dirname, int mode)
|
||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
*path = '\\';
|
*path = '\\';
|
||||||
/* Run through the string and attempt creating all subdirs on the path */
|
/* Run through the string and attempt creating all subdirs on the path */
|
||||||
for (ptr = path+1; *ptr; ptr ++)
|
for (ptr = path+1; *ptr; ptr ++) {
|
||||||
{
|
if (*ptr == '\\' || *ptr == '/') {
|
||||||
if (*ptr == '\\' || *ptr == '/')
|
|
||||||
{
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
|
||||||
CreateDirectory(pathUnc, 0);
|
CreateDirectory(pathUnc, 0);
|
||||||
|
@ -313,373 +314,40 @@ void mkdir(char* dirname, int mode)
|
||||||
CreateDirectory(pathUnc, 0);
|
CreateDirectory(pathUnc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used in DEVICES.C and UI.C for some purpose. Not critical in this port */
|
|
||||||
int system(const char* path) { return 0; }
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
char *tmpnam(char *string)
|
|
||||||
{
|
|
||||||
TCHAR pTemp[MAX_PATH+1];
|
|
||||||
static char buffer[MAX_PATH+1];
|
|
||||||
GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp);
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, pTemp, -1, buffer, MAX_PATH, NULL, NULL);
|
|
||||||
|
|
||||||
if (string)
|
|
||||||
{
|
|
||||||
strcpy(string, buffer);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *tmpfile()
|
|
||||||
{
|
|
||||||
TCHAR pTemp[MAX_PATH+1];
|
|
||||||
if (!GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp))
|
|
||||||
return _wfopen(pTemp, TEXT("w+b"));
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rewind(FILE *stream)
|
|
||||||
{
|
|
||||||
fseek(stream, 0, SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if _WIN32_WCE < 300
|
|
||||||
|
|
||||||
int isalnum(int c) {
|
|
||||||
return ((c >= 'A' && c <= 'Z') ||
|
|
||||||
(c >= 'a' && c <= 'z') ||
|
|
||||||
(c >= '0' && c <= '9'));
|
|
||||||
}
|
|
||||||
|
|
||||||
char *_strdup(const char *strSource)
|
|
||||||
#else
|
|
||||||
char *strdup(const char *strSource)
|
char *strdup(const char *strSource)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
char* buffer;
|
char* buffer;
|
||||||
buffer = (char*)malloc(strlen(strSource)+1);
|
size_z len = strlen(strSource)+1;
|
||||||
|
buffer = (char*)malloc(len);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
strcpy(buffer, strSource);
|
memcpy(buffer, strSource, len);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Very limited implementation of sys/time.h */
|
|
||||||
void usleep(long usec)
|
|
||||||
{
|
|
||||||
long msec = usec/1000;
|
|
||||||
if (msec <= 0)
|
|
||||||
Sleep(0);
|
|
||||||
else
|
|
||||||
Sleep(msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This may provide for better sync mechanism */
|
|
||||||
unsigned int clock()
|
|
||||||
{
|
|
||||||
return GetTickCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And why do people use this? */
|
|
||||||
#if _WIN32_WCE >= 300
|
|
||||||
void abort()
|
|
||||||
{
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
IMHO, no project should use this one, it is not portable at all. This implementation
|
|
||||||
at least allows some projects to work.
|
|
||||||
*/
|
|
||||||
char* getenv(char* name)
|
|
||||||
{
|
|
||||||
static char buffer[MAX_PATH+1];
|
|
||||||
if (strcmp(name, "HOME") == 0 || strcmp(name, "HOMEDIR") == 0)
|
|
||||||
{
|
|
||||||
getcwd(buffer, MAX_PATH);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _WIN32_WCE < 300 || defined(_TEST_HPC_STDIO)
|
|
||||||
|
|
||||||
void *calloc(size_t n, size_t s) {
|
|
||||||
void *result = malloc(n * s);
|
|
||||||
if (result)
|
|
||||||
memset(result, 0, n * s);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *strpbrk(const char *s, const char *accept) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!s || !accept)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i=0; i<strlen(s); i++) {
|
|
||||||
int j;
|
|
||||||
for (j=0; j<strlen(accept); j++)
|
|
||||||
if (s[i] == accept[j])
|
|
||||||
return (char*)&s[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _TEST_HPC_STDIO
|
|
||||||
|
|
||||||
int isdigit(int c) {
|
|
||||||
return (c >='0' && c <= '9');
|
|
||||||
}
|
|
||||||
|
|
||||||
int isprint(int c) {
|
|
||||||
return (c >= ' ' && c <= '~');
|
|
||||||
}
|
|
||||||
|
|
||||||
int isspace(int c) {
|
|
||||||
return (c == ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32_PLATFORM_HPCPRO
|
|
||||||
|
|
||||||
|
|
||||||
int printf(const char *format, ...) {
|
|
||||||
// useless anyway :)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *fopen(const char *path, const char *mode) {
|
|
||||||
TCHAR tempo[MAX_PATH];
|
|
||||||
HANDLE result;
|
|
||||||
bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
|
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, path, strlen(path) + 1, tempo, sizeof(tempo));
|
|
||||||
|
|
||||||
result = CreateFile(tempo, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (result == INVALID_HANDLE_VALUE)
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return (FILE*)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE * _wfopen(const TCHAR *path, const TCHAR *mode) {
|
|
||||||
HANDLE result;
|
|
||||||
bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
|
|
||||||
result = CreateFile(path, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (result == INVALID_HANDLE_VALUE)
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return (FILE*)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *_wfreopen(const TCHAR *path, const TCHAR *mode, FILE *stream) {
|
|
||||||
fclose(stream);
|
|
||||||
stream = _wfopen(path, mode);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fclose(FILE *stream) {
|
|
||||||
CloseHandle((HANDLE)stream);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fseek(FILE *stream, long offset, int whence) {
|
|
||||||
SetFilePointer((HANDLE)stream, offset, NULL, (whence == SEEK_CUR ? FILE_CURRENT : whence == SEEK_END ? FILE_END : FILE_BEGIN));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long ftell(FILE *stream) {
|
|
||||||
return (SetFilePointer((HANDLE)stream, 0, NULL, FILE_CURRENT));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
|
|
||||||
DWORD sizeWritten;
|
|
||||||
|
|
||||||
WriteFile((HANDLE)stream, ptr, size * nmemb, &sizeWritten, NULL);
|
|
||||||
|
|
||||||
if (size != 0)
|
|
||||||
return sizeWritten / size;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
|
|
||||||
DWORD sizeRead;
|
|
||||||
|
|
||||||
ReadFile((HANDLE)stream, ptr, size * nmemb, &sizeRead, NULL);
|
|
||||||
|
|
||||||
if (size != 0)
|
|
||||||
return sizeRead / size;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fgetc(FILE *stream) {
|
|
||||||
unsigned char c;
|
|
||||||
if (fread(&c, 1, 1, stream) != 1)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fgets(char *s, int size, FILE *stream) {
|
|
||||||
int i = 0;
|
|
||||||
char tempo[1];
|
|
||||||
|
|
||||||
memset(s, 0, size);
|
|
||||||
while (fread(tempo, 1, 1, stream)) {
|
|
||||||
//if (tempo[0] == '\r')
|
|
||||||
// break;
|
|
||||||
if (tempo[0] == '\r')
|
|
||||||
continue;
|
|
||||||
s[i++] = tempo[0];
|
|
||||||
if (tempo[0] == '\n')
|
|
||||||
break;
|
|
||||||
if (i == size)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!i)
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int feof(FILE *stream) {
|
|
||||||
DWORD fileSize;
|
|
||||||
DWORD filePos;
|
|
||||||
fileSize = GetFileSize((HANDLE)stream, NULL);
|
|
||||||
filePos = SetFilePointer((HANDLE)stream, 0, 0, FILE_CURRENT);
|
|
||||||
return (filePos == 0xFFFFFFFF || filePos > (fileSize - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
int ferror(FILE *stream) {
|
|
||||||
return 0; // FIXME !
|
|
||||||
}
|
|
||||||
|
|
||||||
int fprintf(FILE *stream, const char *format, ...) {
|
|
||||||
char buf[1024];
|
|
||||||
va_list va;
|
|
||||||
|
|
||||||
va_start(va, format);
|
|
||||||
vsnprintf(buf, 1024, format, va);
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
if (buf[strlen(buf) - 1] == '\n') {
|
|
||||||
int i = strlen(buf) - 1;
|
|
||||||
buf[i] = '\r';
|
|
||||||
buf[i + 1] = '\n';
|
|
||||||
buf[i + 2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fwrite(buf, 1, strlen(buf), stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* _getstdfilex(int) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearerr(FILE *stream) {
|
|
||||||
}
|
|
||||||
|
|
||||||
int fflush(FILE *stream) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int stricmp( const char *string1, const char *string2 ) {
|
|
||||||
char src[4096];
|
|
||||||
char dest[4096];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<strlen(string1); i++)
|
|
||||||
if (string1[i] >= 'A' && string1[i] <= 'Z')
|
|
||||||
src[i] = string1[i] + 32;
|
|
||||||
else
|
|
||||||
src[i] = string1[i];
|
|
||||||
src[i] = 0;
|
|
||||||
|
|
||||||
for (i=0; i<strlen(string2); i++)
|
|
||||||
if (string2[i] >= 'A' && string2[i] <= 'Z')
|
|
||||||
dest[i] = string2[i] + 32;
|
|
||||||
else
|
|
||||||
dest[i] = string2[i];
|
|
||||||
dest[i] = 0;
|
|
||||||
|
|
||||||
return strcmp(src, dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *strrchr(const char *s, int c) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = strlen(s) - 1; i > 0; i--)
|
|
||||||
if (s[i] == c)
|
|
||||||
return (char*)(s + i);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
long int strtol(const char *nptr, char **endptr, int base) {
|
|
||||||
// not correct but that's all we are using
|
|
||||||
|
|
||||||
long int result;
|
|
||||||
sscanf(nptr, "%ld", &result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// gcc build only functions follow
|
// gcc build only functions follow
|
||||||
#else // defined(__GNUC__)
|
#else // defined(__GNUC__)
|
||||||
|
|
||||||
#ifndef __MINGW32CE__
|
#ifndef __MINGW32CE__
|
||||||
int islower(int c)
|
int islower(int c) {
|
||||||
{
|
|
||||||
return (c>='a' && c<='z');
|
return (c>='a' && c<='z');
|
||||||
}
|
}
|
||||||
|
|
||||||
int isspace(int c)
|
int isspace(int c) {
|
||||||
{
|
|
||||||
return (c==' ' || c=='\f' || c=='\n' || c=='\r' || c=='\t' || c=='\v');
|
return (c==' ' || c=='\f' || c=='\n' || c=='\r' || c=='\t' || c=='\v');
|
||||||
}
|
}
|
||||||
|
|
||||||
int isalpha(int c)
|
int isalpha(int c) {
|
||||||
{
|
return ((c>='a' && c<='z') || (c>='A' && c<='Z'));
|
||||||
return (islower(c) || (c>='A' && c<='Z'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int isalnum(int c)
|
int isalnum(int c) {
|
||||||
{
|
return ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'));
|
||||||
return (isalpha(c) || (c>='0' && c<='9'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int isprint(int c)
|
int isprint(int c) {
|
||||||
{
|
//static const char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~";
|
||||||
static char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~";
|
//return (isalnum(c) || strchr(punct, c));
|
||||||
int i = 0, flag = 0;
|
return (32 <= c && c <= 126); // based on BSD manpage
|
||||||
while ((punct[i] != 0) && (flag = (punct[i] != c)))
|
|
||||||
i++;
|
|
||||||
return (isalnum(c) || flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int atexit(void (*function)(void))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const Pla
|
||||||
const PlainGameDescriptor *g = list;
|
const PlainGameDescriptor *g = list;
|
||||||
while (g->gameid) {
|
while (g->gameid) {
|
||||||
if (0 == scumm_stricmp(gameid, g->gameid))
|
if (0 == scumm_stricmp(gameid, g->gameid))
|
||||||
break;
|
return g;
|
||||||
g++;
|
g++;
|
||||||
}
|
}
|
||||||
return g;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameDescriptor::updateDesc(const char *extra) {
|
void GameDescriptor::updateDesc(const char *extra) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct PlainGameDescriptor {
|
||||||
/**
|
/**
|
||||||
* Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
|
* Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
|
||||||
* matching the given gameid. If not match is found return 0.
|
* matching the given gameid. If not match is found return 0.
|
||||||
* The end of the list marked by a PlainGameDescriptor with gameid equal to 0.
|
* The end of the list must marked by a PlainGameDescriptor with gameid equal to 0.
|
||||||
*/
|
*/
|
||||||
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
|
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define SCUMMVM_VERSION "0.12.0svn"
|
#define SCUMMVM_VERSION "0.13.0svn"
|
||||||
|
|
|
@ -81,17 +81,11 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX];
|
||||||
#define STATIC_PLUGIN 1
|
#define STATIC_PLUGIN 1
|
||||||
#define DYNAMIC_PLUGIN 2
|
#define DYNAMIC_PLUGIN 2
|
||||||
|
|
||||||
// Note: The spaces around ENABLE_##ID have been added on purpose for
|
|
||||||
// MSVC. For some reason, MSVC tries to add the parenthesis after
|
|
||||||
// ENABLE_##ID to the check, thus making it false all the time.
|
|
||||||
// Please do NOT remove them, otherwise no engine plugins will be
|
|
||||||
// registered under MSVC
|
|
||||||
|
|
||||||
#define PLUGIN_ENABLED_STATIC(ID) \
|
#define PLUGIN_ENABLED_STATIC(ID) \
|
||||||
(defined( ENABLE_##ID ) && !PLUGIN_ENABLED_DYNAMIC(ID))
|
(ENABLE_##ID && !PLUGIN_ENABLED_DYNAMIC(ID))
|
||||||
|
|
||||||
#define PLUGIN_ENABLED_DYNAMIC(ID) \
|
#define PLUGIN_ENABLED_DYNAMIC(ID) \
|
||||||
(defined( ENABLE_##ID ) && (ENABLE_##ID == DYNAMIC_PLUGIN) && defined(DYNAMIC_MODULES))
|
(ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN) && DYNAMIC_MODULES)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REGISTER_PLUGIN_STATIC is a convenience macro which is used to declare
|
* REGISTER_PLUGIN_STATIC is a convenience macro which is used to declare
|
||||||
|
|
|
@ -176,7 +176,6 @@ void ConfigManager::loadFile(const String &filename) {
|
||||||
if (!cfg_file.open(filename)) {
|
if (!cfg_file.open(filename)) {
|
||||||
printf("Creating configuration file: %s\n", filename.c_str());
|
printf("Creating configuration file: %s\n", filename.c_str());
|
||||||
} else {
|
} else {
|
||||||
char buf[MAXLINELEN];
|
|
||||||
String domain;
|
String domain;
|
||||||
String comment;
|
String comment;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
|
@ -184,20 +183,28 @@ void ConfigManager::loadFile(const String &filename) {
|
||||||
// TODO: Detect if a domain occurs multiple times (or likewise, if
|
// TODO: Detect if a domain occurs multiple times (or likewise, if
|
||||||
// a key occurs multiple times inside one domain).
|
// a key occurs multiple times inside one domain).
|
||||||
|
|
||||||
while (!cfg_file.eof()) {
|
while (!cfg_file.eof() && !cfg_file.ioFailed()) {
|
||||||
lineno++;
|
lineno++;
|
||||||
if (!cfg_file.readLine(buf, MAXLINELEN))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (buf[0] == '#') {
|
// Read a line
|
||||||
|
String line;
|
||||||
|
while (line.lastChar() != '\n') {
|
||||||
|
char buf[MAXLINELEN];
|
||||||
|
if (!cfg_file.readLine_NEW(buf, MAXLINELEN))
|
||||||
|
break;
|
||||||
|
line += buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.size() == 0) {
|
||||||
|
// Do nothing
|
||||||
|
} else if (line[0] == '#') {
|
||||||
// Accumulate comments here. Once we encounter either the start
|
// Accumulate comments here. Once we encounter either the start
|
||||||
// of a new domain, or a key-value-pair, we associate the value
|
// of a new domain, or a key-value-pair, we associate the value
|
||||||
// of the 'comment' variable with that entity.
|
// of the 'comment' variable with that entity.
|
||||||
comment += buf;
|
comment += line;
|
||||||
comment += '\n';
|
} else if (line[0] == '[') {
|
||||||
} else if (buf[0] == '[') {
|
|
||||||
// It's a new domain which begins here.
|
// It's a new domain which begins here.
|
||||||
char *p = buf + 1;
|
const char *p = line.c_str() + 1;
|
||||||
// Get the domain name, and check whether it's valid (that
|
// Get the domain name, and check whether it's valid (that
|
||||||
// is, verify that it only consists of alphanumerics,
|
// is, verify that it only consists of alphanumerics,
|
||||||
// dashes and underscores).
|
// dashes and underscores).
|
||||||
|
@ -209,8 +216,8 @@ void ConfigManager::loadFile(const String &filename) {
|
||||||
error("Config file buggy: missing ] in line %d", lineno);
|
error("Config file buggy: missing ] in line %d", lineno);
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
*p = 0;
|
domain = String(line.c_str() + 1, p - (line.c_str() + 1));
|
||||||
domain = buf + 1;
|
//domain = String(line.c_str() + 1, p); // TODO: Pending Common::String changes
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Config file buggy: Invalid character '%c' occured in domain name in line %d", *p, lineno);
|
error("Config file buggy: Invalid character '%c' occured in domain name in line %d", *p, lineno);
|
||||||
|
@ -226,10 +233,14 @@ void ConfigManager::loadFile(const String &filename) {
|
||||||
|
|
||||||
_domainSaveOrder.push_back(domain);
|
_domainSaveOrder.push_back(domain);
|
||||||
} else {
|
} else {
|
||||||
// Skip leading & trailing whitespaces
|
// This line should be a line with a 'key=value' pair, or an empty one.
|
||||||
char *t = rtrim(ltrim(buf));
|
|
||||||
|
// Skip leading whitespaces
|
||||||
|
const char *t = line.c_str();
|
||||||
|
while (isspace(*t))
|
||||||
|
t++;
|
||||||
|
|
||||||
// Skip empty lines
|
// Skip empty lines / lines with only whitespace
|
||||||
if (*t == 0)
|
if (*t == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -238,13 +249,30 @@ void ConfigManager::loadFile(const String &filename) {
|
||||||
error("Config file buggy: Key/value pair found outside a domain in line %d", lineno);
|
error("Config file buggy: Key/value pair found outside a domain in line %d", lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split string at '=' into 'key' and 'value'.
|
// Split string at '=' into 'key' and 'value'. First, find the "=" delimeter.
|
||||||
char *p = strchr(t, '=');
|
const char *p = strchr(t, '=');
|
||||||
if (!p)
|
if (!p)
|
||||||
error("Config file buggy: Junk found in line line %d: '%s'", lineno, t);
|
error("Config file buggy: Junk found in line line %d: '%s'", lineno, t);
|
||||||
*p = 0;
|
|
||||||
String key = rtrim(t);
|
// Trim spaces before the '=' to obtain the key
|
||||||
String value = ltrim(p + 1);
|
const char *p2 = p;
|
||||||
|
while (p2 > t && isspace(*(p2-1)))
|
||||||
|
p2--;
|
||||||
|
String key(t, p2 - t);
|
||||||
|
|
||||||
|
// Skip spaces after the '='
|
||||||
|
t = p + 1;
|
||||||
|
while (isspace(*t))
|
||||||
|
t++;
|
||||||
|
|
||||||
|
// Trim trailing spaces
|
||||||
|
p2 = t + strlen(t);
|
||||||
|
while (p2 > t && isspace(*(p2-1)))
|
||||||
|
p2--;
|
||||||
|
|
||||||
|
String value(t, p2 - t);
|
||||||
|
|
||||||
|
// Finally, store the key/value pair in the active domain
|
||||||
set(key, value, domain);
|
set(key, value, domain);
|
||||||
|
|
||||||
// Store comment
|
// Store comment
|
||||||
|
|
|
@ -452,10 +452,12 @@ bool File::isOpen() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool File::ioFailed() const {
|
bool File::ioFailed() const {
|
||||||
|
// TODO/FIXME: Just use ferror() here?
|
||||||
return _ioFailed != 0;
|
return _ioFailed != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::clearIOFailed() {
|
void File::clearIOFailed() {
|
||||||
|
// TODO/FIXME: Just use clearerr() here?
|
||||||
_ioFailed = false;
|
_ioFailed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,32 +43,43 @@ static int computeCapacity(int len) {
|
||||||
return ((len + 32 - 1) & ~0x1F) - 1;
|
return ((len + 32 - 1) & ~0x1F) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const char *str, uint32 len)
|
String::String(const char *str) : _len(0), _str(_storage) {
|
||||||
: _len(0), _str(_storage) {
|
if (str == 0) {
|
||||||
|
_storage[0] = 0;
|
||||||
|
_len = 0;
|
||||||
|
} else
|
||||||
|
initWithCStr(str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const char *str, uint32 len) : _len(0), _str(_storage) {
|
||||||
|
initWithCStr(str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const char *beginP, const char *endP) : _len(0), _str(_storage) {
|
||||||
|
assert(endP >= beginP);
|
||||||
|
initWithCStr(beginP, endP - beginP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::initWithCStr(const char *str, uint32 len) {
|
||||||
|
assert(str);
|
||||||
|
|
||||||
// Init _storage member explicitly (ie. without calling its constructor)
|
// Init _storage member explicitly (ie. without calling its constructor)
|
||||||
// for GCC 2.95.x compatibility (see also tracker item #1602879).
|
// for GCC 2.95.x compatibility (see also tracker item #1602879).
|
||||||
_storage[0] = 0;
|
_storage[0] = 0;
|
||||||
|
|
||||||
if (str && *str) {
|
_len = len;
|
||||||
const uint32 tmp = strlen(str);
|
|
||||||
assert(len <= tmp);
|
|
||||||
if (len <= 0)
|
|
||||||
len = tmp;
|
|
||||||
_len = len;
|
|
||||||
|
|
||||||
if (len >= _builtinCapacity) {
|
if (len >= _builtinCapacity) {
|
||||||
// Not enough internal storage, so allocate more
|
// Not enough internal storage, so allocate more
|
||||||
_extern._capacity = computeCapacity(len);
|
_extern._capacity = computeCapacity(len);
|
||||||
_extern._refCount = 0;
|
_extern._refCount = 0;
|
||||||
_str = (char *)malloc(_extern._capacity+1);
|
_str = (char *)malloc(_extern._capacity+1);
|
||||||
assert(_str != 0);
|
assert(_str != 0);
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the string into the storage area
|
|
||||||
memcpy(_str, str, len);
|
|
||||||
_str[len] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the string into the storage area
|
||||||
|
memmove(_str, str, len);
|
||||||
|
_str[len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const String &str)
|
String::String(const String &str)
|
||||||
|
@ -91,6 +102,8 @@ String::String(char c)
|
||||||
_storage[0] = c;
|
_storage[0] = c;
|
||||||
_storage[1] = 0;
|
_storage[1] = 0;
|
||||||
|
|
||||||
|
// TODO/FIXME: There is no reason for the following check -- we *do*
|
||||||
|
// allow strings to contain 0 bytes!
|
||||||
_len = (c == 0) ? 0 : 1;
|
_len = (c == 0) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +143,14 @@ String& String::operator =(const char *str) {
|
||||||
uint32 len = strlen(str);
|
uint32 len = strlen(str);
|
||||||
ensureCapacity(len, false);
|
ensureCapacity(len, false);
|
||||||
_len = len;
|
_len = len;
|
||||||
memcpy(_str, str, len + 1);
|
memmove(_str, str, len + 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator =(const String &str) {
|
String &String::operator =(const String &str) {
|
||||||
|
if (&str == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
if (str.isStorageIntern()) {
|
if (str.isStorageIntern()) {
|
||||||
decRefCount(_extern._refCount);
|
decRefCount(_extern._refCount);
|
||||||
_len = str._len;
|
_len = str._len;
|
||||||
|
|
19
common/str.h
19
common/str.h
|
@ -96,10 +96,24 @@ public:
|
||||||
static const char *emptyString;
|
static const char *emptyString;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Construct a new empty string. */
|
||||||
String() : _len(0), _str(_storage) { _storage[0] = 0; }
|
String() : _len(0), _str(_storage) { _storage[0] = 0; }
|
||||||
String(const char *str, uint32 len = 0);
|
|
||||||
|
/** Construct a new string from the given NULL-terminated C string. */
|
||||||
|
String(const char *str);
|
||||||
|
|
||||||
|
/** Construct a new string containing exactly len characters read from address str. */
|
||||||
|
String(const char *str, uint32 len);
|
||||||
|
|
||||||
|
/** Construct a new string containing the characters between beginP (including) and endP (excluding). */
|
||||||
|
String(const char *beginP, const char *endP);
|
||||||
|
|
||||||
|
/** Construct a copy of the given string. */
|
||||||
String(const String &str);
|
String(const String &str);
|
||||||
|
|
||||||
|
/** Construct a string consisting of the given character. */
|
||||||
String(char c);
|
String(char c);
|
||||||
|
|
||||||
~String();
|
~String();
|
||||||
|
|
||||||
String &operator =(const char *str);
|
String &operator =(const char *str);
|
||||||
|
@ -162,7 +176,7 @@ public:
|
||||||
|
|
||||||
void toLowercase();
|
void toLowercase();
|
||||||
void toUppercase();
|
void toUppercase();
|
||||||
|
|
||||||
uint hash() const;
|
uint hash() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -189,6 +203,7 @@ protected:
|
||||||
void ensureCapacity(uint32 new_len, bool keep_old);
|
void ensureCapacity(uint32 new_len, bool keep_old);
|
||||||
void incRefCount() const;
|
void incRefCount() const;
|
||||||
void decRefCount(int *oldRefCount);
|
void decRefCount(int *oldRefCount);
|
||||||
|
void initWithCStr(const char *str, uint32 len);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Append two strings to form a new (temp) string
|
// Append two strings to form a new (temp) string
|
||||||
|
|
|
@ -148,6 +148,61 @@ char *SeekableReadStream::readLine(char *buf, size_t bufSize) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *SeekableReadStream::readLine_NEW(char *buf, size_t bufSize) {
|
||||||
|
assert(buf != 0 && bufSize > 1);
|
||||||
|
char *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
char c = 0;
|
||||||
|
|
||||||
|
// If end-of-file occurs before any characters are read, return NULL
|
||||||
|
// and the buffer contents remain unchanged.
|
||||||
|
if (eos() || ioFailed()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop as long as the stream has not ended, there is still free
|
||||||
|
// space in the buffer, and the line has not ended
|
||||||
|
while (!eos() && len + 1 < bufSize && c != LF) {
|
||||||
|
c = readByte();
|
||||||
|
|
||||||
|
// If end-of-file occurs before any characters are read, return
|
||||||
|
// NULL and the buffer contents remain unchanged. If an error
|
||||||
|
/// occurs, return NULL and the buffer contents are indeterminate.
|
||||||
|
if (ioFailed() || (len == 0 && eos()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Check for CR or CR/LF
|
||||||
|
// * DOS and Windows use CRLF line breaks
|
||||||
|
// * Unix and OS X use LF line breaks
|
||||||
|
// * Macintosh before OS X used CR line breaks
|
||||||
|
if (c == CR) {
|
||||||
|
// Look at the next char -- is it LF? If not, seek back
|
||||||
|
c = readByte();
|
||||||
|
if (c != LF && !eos())
|
||||||
|
seek(-1, SEEK_CUR);
|
||||||
|
// Treat CR & CR/LF as plain LF
|
||||||
|
c = LF;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p++ = c;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
// This should fix a bug while using readLine with Common::File
|
||||||
|
// it seems that it sets the eos flag after an invalid read
|
||||||
|
// and at the same time the ioFailed flag
|
||||||
|
// the config file parser fails out of that reason for the new themes
|
||||||
|
if (eos()) {
|
||||||
|
clearIOFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We always terminate the buffer if no error occured
|
||||||
|
*p = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32 SubReadStream::read(void *dataPtr, uint32 dataSize) {
|
uint32 SubReadStream::read(void *dataPtr, uint32 dataSize) {
|
||||||
dataSize = MIN(dataSize, _end - _pos);
|
dataSize = MIN(dataSize, _end - _pos);
|
||||||
|
|
||||||
|
|
|
@ -304,13 +304,40 @@ public:
|
||||||
* Read one line of text from a CR or CR/LF terminated plain text file.
|
* Read one line of text from a CR or CR/LF terminated plain text file.
|
||||||
* This method is a rough analog of the (f)gets function.
|
* This method is a rough analog of the (f)gets function.
|
||||||
*
|
*
|
||||||
|
* @bug A main difference (and flaw) in this function is that there is no
|
||||||
|
* way to detect that a line exceeeds the length of the buffer.
|
||||||
|
* Code which needs this should use the new readLine_NEW() method instead.
|
||||||
|
*
|
||||||
* @param buf the buffer to store into
|
* @param buf the buffer to store into
|
||||||
* @param bufSize the size of the buffer
|
* @param bufSize the size of the buffer
|
||||||
* @return a pointer to the read string, or NULL if an error occurred
|
* @return a pointer to the read string, or NULL if an error occurred
|
||||||
|
*
|
||||||
* @note The line terminator (CR or CR/LF) is stripped and not inserted
|
* @note The line terminator (CR or CR/LF) is stripped and not inserted
|
||||||
* into the buffer.
|
* into the buffer.
|
||||||
*/
|
*/
|
||||||
virtual char *readLine(char *buf, size_t bufSize);
|
virtual char *readLine(char *buf, size_t bufSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most one less than the number of characters specified
|
||||||
|
* by bufSize from the and stores them in the string buf. Reading
|
||||||
|
* stops when the end of a line is reached (CR, CR/LF or LF), at
|
||||||
|
* end-of-file or error. The newline, if any, is retained (CR and
|
||||||
|
* CR/LF are translated to LF = 0xA = '\n'). If any characters are
|
||||||
|
* read and there is no error, a `\0' character is appended to end
|
||||||
|
* the string.
|
||||||
|
*
|
||||||
|
* Upon successful completion, return a pointer to the string. If
|
||||||
|
* end-of-file occurs before any characters are read, returns NULL
|
||||||
|
* and the buffer contents remain unchanged. If an error occurs,
|
||||||
|
* returns NULL and the buffer contents are indeterminate.
|
||||||
|
* This method does not distinguish between end-of-file and error;
|
||||||
|
* callers muse use ioFailed() or eos() to determine which occurred.
|
||||||
|
*
|
||||||
|
* @param buf the buffer to store into
|
||||||
|
* @param bufSize the size of the buffer
|
||||||
|
* @return a pointer to the read string, or NULL if an error occurred
|
||||||
|
*/
|
||||||
|
virtual char *readLine_NEW(char *s, size_t bufSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
4
configure
vendored
4
configure
vendored
|
@ -129,10 +129,10 @@ _srcdir=`dirname $0`
|
||||||
if type mktemp > /dev/null 2>&1 ; then
|
if type mktemp > /dev/null 2>&1 ; then
|
||||||
TMPO=`mktemp /tmp/scummvm-conf.XXXXXXXXXX`
|
TMPO=`mktemp /tmp/scummvm-conf.XXXXXXXXXX`
|
||||||
else
|
else
|
||||||
TMPO=${_srcdir}/scummvm-conf
|
TMPO=scummvm-conf
|
||||||
fi
|
fi
|
||||||
TMPC=${TMPO}.cpp
|
TMPC=${TMPO}.cpp
|
||||||
TMPLOG=${_srcdir}/config.log
|
TMPLOG=config.log
|
||||||
|
|
||||||
# For cross compiling
|
# For cross compiling
|
||||||
_host=""
|
_host=""
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Prologue information
|
# Prologue information
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
Name : scummvm
|
Name : scummvm
|
||||||
Version : 0.12.0svn
|
Version : 0.13.0svn
|
||||||
Release : 1
|
Release : 1
|
||||||
Summary : Graphic adventure game interpreter
|
Summary : Graphic adventure game interpreter
|
||||||
Group : Interpreters
|
Group : Interpreters
|
||||||
|
|
|
@ -7,8 +7,8 @@ IDI_ICON ICON DISCARDABLE "../../icons/scummvm.ico"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,12,0,0
|
FILEVERSION 0,13,0,0
|
||||||
PRODUCTVERSION 0,12,0,0
|
PRODUCTVERSION 0,13,0,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -25,13 +25,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "Look! A three headed monkey (TM)! .. Nice use of the TM!\0"
|
VALUE "Comments", "Look! A three headed monkey (TM)! .. Nice use of the TM!\0"
|
||||||
VALUE "FileDescription", "http://www.scummvm.org/\0"
|
VALUE "FileDescription", "http://www.scummvm.org/\0"
|
||||||
VALUE "FileVersion", "0.12.0svn\0"
|
VALUE "FileVersion", "0.13.0svn\0"
|
||||||
VALUE "InternalName", "scummvm\0"
|
VALUE "InternalName", "scummvm\0"
|
||||||
VALUE "LegalCopyright", "Copyright © 2001-2007 The ScummVM Team\0"
|
VALUE "LegalCopyright", "Copyright © 2001-2007 The ScummVM Team\0"
|
||||||
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
|
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
|
||||||
VALUE "OriginalFilename", "scummvm.exe\0"
|
VALUE "OriginalFilename", "scummvm.exe\0"
|
||||||
VALUE "ProductName", "ScummVM\0"
|
VALUE "ProductName", "ScummVM\0"
|
||||||
VALUE "ProductVersion", "0.12.0svn\0"
|
VALUE "ProductVersion", "0.13.0svn\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -8,7 +8,7 @@ if [ "$TMP" = "" ]; then
|
||||||
fi
|
fi
|
||||||
PKG=$TMP/package-scummvm
|
PKG=$TMP/package-scummvm
|
||||||
|
|
||||||
VERSION=0.12.0svn
|
VERSION=0.13.0svn
|
||||||
ARCH=i486
|
ARCH=i486
|
||||||
BUILD=1
|
BUILD=1
|
||||||
|
|
||||||
|
|
|
@ -1076,6 +1076,8 @@ protected:
|
||||||
virtual void drawImage(VC10_state *state);
|
virtual void drawImage(VC10_state *state);
|
||||||
void drawBackGroundImage(VC10_state *state);
|
void drawBackGroundImage(VC10_state *state);
|
||||||
void drawVertImage(VC10_state *state);
|
void drawVertImage(VC10_state *state);
|
||||||
|
void drawVertImageCompressed(VC10_state *state);
|
||||||
|
void drawVertImageUncompressed(VC10_state *state);
|
||||||
|
|
||||||
void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height);
|
void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height);
|
||||||
|
|
||||||
|
|
|
@ -744,10 +744,6 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGOSEngine::drawBackGroundImage(VC10_state *state) {
|
void AGOSEngine::drawBackGroundImage(VC10_state *state) {
|
||||||
const byte *src;
|
|
||||||
byte *dst;
|
|
||||||
uint h, i;
|
|
||||||
|
|
||||||
state->width = _screenWidth;
|
state->width = _screenWidth;
|
||||||
if (_window3Flag == 1) {
|
if (_window3Flag == 1) {
|
||||||
state->width = 0;
|
state->width = 0;
|
||||||
|
@ -755,15 +751,19 @@ void AGOSEngine::drawBackGroundImage(VC10_state *state) {
|
||||||
state->y_skip = 0;
|
state->y_skip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = state->srcPtr + (state->width * state->y_skip) + (state->x_skip * 8);
|
const byte* src = state->srcPtr + (state->width * state->y_skip) + (state->x_skip * 8);
|
||||||
dst = state->surf_addr;
|
byte* dst = state->surf_addr;
|
||||||
|
|
||||||
state->draw_width *= 2;
|
state->draw_width *= 2;
|
||||||
|
|
||||||
h = state->draw_height;
|
uint h = state->draw_height;
|
||||||
|
const uint w = state->draw_width;
|
||||||
|
const byte paletteMod = state->paletteMod;
|
||||||
do {
|
do {
|
||||||
for (i = 0; i != state->draw_width; i++)
|
for (uint i = 0; i != w; i+=2) {
|
||||||
dst[i] = src[i] + state->paletteMod;
|
dst[i] = src[i] + paletteMod;
|
||||||
|
dst[i+1] = src[i+1] + paletteMod;
|
||||||
|
}
|
||||||
dst += state->surf_pitch;
|
dst += state->surf_pitch;
|
||||||
src += state->width;
|
src += state->width;
|
||||||
} while (--h);
|
} while (--h);
|
||||||
|
@ -771,63 +771,86 @@ void AGOSEngine::drawBackGroundImage(VC10_state *state) {
|
||||||
|
|
||||||
void AGOSEngine::drawVertImage(VC10_state *state) {
|
void AGOSEngine::drawVertImage(VC10_state *state) {
|
||||||
if (state->flags & kDFCompressed) {
|
if (state->flags & kDFCompressed) {
|
||||||
uint w, h;
|
drawVertImageCompressed(state);
|
||||||
byte *src, *dst, *dstPtr;
|
} else {
|
||||||
|
drawVertImageUncompressed(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state->x_skip *= 4; /* reached */
|
void AGOSEngine::drawVertImageUncompressed(VC10_state *state) {
|
||||||
|
assert ((state->flags & kDFCompressed) == 0) ;
|
||||||
|
|
||||||
state->dl = state->width;
|
const byte *src;
|
||||||
state->dh = state->height;
|
byte *dst;
|
||||||
|
uint count;
|
||||||
|
|
||||||
vc10_skip_cols(state);
|
src = state->srcPtr + (state->width * state->y_skip) * 8;
|
||||||
|
dst = state->surf_addr;
|
||||||
|
state->x_skip *= 4;
|
||||||
|
|
||||||
dstPtr = state->surf_addr;
|
do {
|
||||||
if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
|
for (count = 0; count != state->draw_width; count++) {
|
||||||
dstPtr += vcReadVar(252);
|
|
||||||
}
|
|
||||||
w = 0;
|
|
||||||
do {
|
|
||||||
byte color;
|
byte color;
|
||||||
|
color = (src[count + state->x_skip] / 16) + state->paletteMod;
|
||||||
|
if ((state->flags & kDFNonTrans) || color)
|
||||||
|
dst[count * 2] = color | state->palette;
|
||||||
|
color = (src[count + state->x_skip] & 15) + state->paletteMod;
|
||||||
|
if ((state->flags & kDFNonTrans) || color)
|
||||||
|
dst[count * 2 + 1] = color | state->palette;
|
||||||
|
}
|
||||||
|
dst += state->surf_pitch;
|
||||||
|
src += state->width * 8;
|
||||||
|
} while (--state->draw_height);
|
||||||
|
}
|
||||||
|
|
||||||
src = vc10_depackColumn(state);
|
void AGOSEngine::drawVertImageCompressed(VC10_state *state) {
|
||||||
dst = dstPtr;
|
assert (state->flags & kDFCompressed) ;
|
||||||
|
uint w, h;
|
||||||
|
|
||||||
h = 0;
|
state->x_skip *= 4; /* reached */
|
||||||
|
|
||||||
|
state->dl = state->width;
|
||||||
|
state->dh = state->height;
|
||||||
|
|
||||||
|
vc10_skip_cols(state);
|
||||||
|
|
||||||
|
byte *dstPtr = state->surf_addr;
|
||||||
|
if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
|
||||||
|
dstPtr += vcReadVar(252);
|
||||||
|
}
|
||||||
|
w = 0;
|
||||||
|
do {
|
||||||
|
byte color;
|
||||||
|
|
||||||
|
const byte *src = vc10_depackColumn(state);
|
||||||
|
byte *dst = dstPtr;
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
if (state->flags & kDFNonTrans) {
|
||||||
do {
|
do {
|
||||||
color = (*src / 16);
|
byte colors = *src;
|
||||||
if ((state->flags & kDFNonTrans) || color != 0)
|
color = (colors / 16);
|
||||||
|
dst[0] = color | state->palette;
|
||||||
|
color = (colors & 15);
|
||||||
|
dst[1] = color | state->palette;
|
||||||
|
dst += state->surf_pitch;
|
||||||
|
src++;
|
||||||
|
} while (++h != state->draw_height);
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
byte colors = *src;
|
||||||
|
color = (colors / 16);
|
||||||
|
if (color != 0)
|
||||||
dst[0] = color | state->palette;
|
dst[0] = color | state->palette;
|
||||||
color = (*src & 15);
|
color = (colors & 15);
|
||||||
if ((state->flags & kDFNonTrans) || color != 0)
|
if (color != 0)
|
||||||
dst[1] = color | state->palette;
|
dst[1] = color | state->palette;
|
||||||
dst += state->surf_pitch;
|
dst += state->surf_pitch;
|
||||||
src++;
|
src++;
|
||||||
} while (++h != state->draw_height);
|
} while (++h != state->draw_height);
|
||||||
dstPtr += 2;
|
}
|
||||||
} while (++w != state->draw_width);
|
dstPtr += 2;
|
||||||
} else {
|
} while (++w != state->draw_width);
|
||||||
const byte *src;
|
|
||||||
byte *dst;
|
|
||||||
uint count;
|
|
||||||
|
|
||||||
src = state->srcPtr + (state->width * state->y_skip) * 8;
|
|
||||||
dst = state->surf_addr;
|
|
||||||
state->x_skip *= 4;
|
|
||||||
|
|
||||||
do {
|
|
||||||
for (count = 0; count != state->draw_width; count++) {
|
|
||||||
byte color;
|
|
||||||
color = (src[count + state->x_skip] / 16) + state->paletteMod;
|
|
||||||
if ((state->flags & kDFNonTrans) || color)
|
|
||||||
dst[count * 2] = color | state->palette;
|
|
||||||
color = (src[count + state->x_skip] & 15) + state->paletteMod;
|
|
||||||
if ((state->flags & kDFNonTrans) || color)
|
|
||||||
dst[count * 2 + 1] = color | state->palette;
|
|
||||||
}
|
|
||||||
dst += state->surf_pitch;
|
|
||||||
src += state->width * 8;
|
|
||||||
} while (--state->draw_height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGOSEngine::drawImage(VC10_state *state) {
|
void AGOSEngine::drawImage(VC10_state *state) {
|
||||||
|
|
|
@ -94,6 +94,7 @@ public:
|
||||||
|
|
||||||
Common::StringList _volumeResourceFiles;
|
Common::StringList _volumeResourceFiles;
|
||||||
StringPtrHashMap _volumeEntriesMap;
|
StringPtrHashMap _volumeEntriesMap;
|
||||||
|
TextHandler _textHandler;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize(void);
|
void initialize(void);
|
||||||
|
@ -107,6 +108,7 @@ private:
|
||||||
extern CineEngine *g_cine;
|
extern CineEngine *g_cine;
|
||||||
|
|
||||||
#define BOOT_PRC_NAME "AUTO00.PRC"
|
#define BOOT_PRC_NAME "AUTO00.PRC"
|
||||||
|
#define COPY_PROT_FAIL_PRC_NAME "L201.ANI"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VAR_MOUSE_X_MODE = 253,
|
VAR_MOUSE_X_MODE = 253,
|
||||||
|
|
|
@ -337,7 +337,7 @@ int FWRenderer::drawChar(char character, int x, int y) {
|
||||||
x += 5;
|
x += 5;
|
||||||
} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
|
} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
|
||||||
idx = fontParamTable[(unsigned char)character].characterIdx;
|
idx = fontParamTable[(unsigned char)character].characterIdx;
|
||||||
drawSpriteRaw(textTable[idx][0], textTable[idx][1], 16, 8, _backBuffer, x, y);
|
drawSpriteRaw(g_cine->_textHandler.textTable[idx][0], g_cine->_textHandler.textTable[idx][1], 16, 8, _backBuffer, x, y);
|
||||||
x += width + 1;
|
x += width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,7 +938,7 @@ int OSRenderer::drawChar(char character, int x, int y) {
|
||||||
x += 5;
|
x += 5;
|
||||||
} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
|
} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
|
||||||
idx = fontParamTable[(unsigned char)character].characterIdx;
|
idx = fontParamTable[(unsigned char)character].characterIdx;
|
||||||
drawSpriteRaw2(textTable[idx][0], 0, 16, 8, _backBuffer, x, y);
|
drawSpriteRaw2(g_cine->_textHandler.textTable[idx][0], 0, 16, 8, _backBuffer, x, y);
|
||||||
x += width + 1;
|
x += width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,9 @@ ScriptList objectScripts;
|
||||||
|
|
||||||
/*! \todo Is script size of 0 valid?
|
/*! \todo Is script size of 0 valid?
|
||||||
* \todo Fix script dump code
|
* \todo Fix script dump code
|
||||||
|
* @return Was the loading successful?
|
||||||
*/
|
*/
|
||||||
void loadPrc(const char *pPrcName) {
|
bool loadPrc(const char *pPrcName) {
|
||||||
byte i;
|
byte i;
|
||||||
uint16 numScripts;
|
uint16 numScripts;
|
||||||
byte *scriptPtr, *dataPtr;
|
byte *scriptPtr, *dataPtr;
|
||||||
|
@ -53,11 +54,11 @@ void loadPrc(const char *pPrcName) {
|
||||||
scriptTable.clear();
|
scriptTable.clear();
|
||||||
|
|
||||||
// This is copy protection. Used to hang the machine
|
// This is copy protection. Used to hang the machine
|
||||||
if (!scumm_stricmp(pPrcName, "L201.ANI")) {
|
if (!scumm_stricmp(pPrcName, COPY_PROT_FAIL_PRC_NAME)) {
|
||||||
Common::Event event;
|
Common::Event event;
|
||||||
event.type = Common::EVENT_RTL;
|
event.type = Common::EVENT_RTL;
|
||||||
g_system->getEventManager()->pushEvent(event);
|
g_system->getEventManager()->pushEvent(event);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDataDisk(-1);
|
checkDataDisk(-1);
|
||||||
|
@ -110,6 +111,8 @@ void loadPrc(const char *pPrcName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Cine
|
} // End of namespace Cine
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Cine {
|
||||||
extern ScriptList globalScripts;
|
extern ScriptList globalScripts;
|
||||||
extern ScriptList objectScripts;
|
extern ScriptList objectScripts;
|
||||||
|
|
||||||
void loadPrc(const char *pPrcName);
|
bool loadPrc(const char *pPrcName);
|
||||||
|
|
||||||
} // End of namespace Cine
|
} // End of namespace Cine
|
||||||
|
|
||||||
|
|
|
@ -1019,6 +1019,20 @@ int FWScript::o1_divVar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int FWScript::o1_compareVar() {
|
int FWScript::o1_compareVar() {
|
||||||
|
// WORKAROUND: A workaround for a script bug in script file CODE2.PRC
|
||||||
|
// in at least some of the Amiga and Atari ST versions of Future Wars.
|
||||||
|
// Fixes bug #2016647 (FW: crash with italian amiga version). A local
|
||||||
|
// variable 251 is compared against value 0 although it's quite apparent
|
||||||
|
// from the context in the script that instead global variable 251 should
|
||||||
|
// be compared against value 0. So looks like someone made a typo when
|
||||||
|
// making the scripts. Therefore we change that particular comparison
|
||||||
|
// from using the local variable 251 to using the global variable 251.
|
||||||
|
if (g_cine->getGameType() == Cine::GType_FW && scumm_stricmp(currentPrcName, "CODE2.PRC") == 0 &&
|
||||||
|
(g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) &&
|
||||||
|
_script.getByte(_pos) == 251 && _script.getByte(_pos + 1) == 0 && _script.getWord(_pos + 2) == 0) {
|
||||||
|
return o1_compareGlobalVar();
|
||||||
|
}
|
||||||
|
|
||||||
byte varIdx = getNextByte();
|
byte varIdx = getNextByte();
|
||||||
byte varType = getNextByte();
|
byte varType = getNextByte();
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ namespace Cine {
|
||||||
|
|
||||||
byte *textDataPtr;
|
byte *textDataPtr;
|
||||||
|
|
||||||
byte textTable[256][2][16 * 8];
|
|
||||||
|
|
||||||
const char **failureMessages;
|
const char **failureMessages;
|
||||||
const CommandeType *defaultActionCommand;
|
const CommandeType *defaultActionCommand;
|
||||||
const CommandeType *systemMenu;
|
const CommandeType *systemMenu;
|
||||||
|
@ -77,14 +75,14 @@ void loadTextData(const char *pFileName, byte *pDestinationBuffer) {
|
||||||
loadRelatedPalette(pFileName);
|
loadRelatedPalette(pFileName);
|
||||||
|
|
||||||
for (i = 0; i < numCharacters; i++) {
|
for (i = 0; i < numCharacters; i++) {
|
||||||
gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 16, 8);
|
gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 16, 8);
|
||||||
generateMask(textTable[i][0], textTable[i][1], 16 * 8, 0);
|
generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 16 * 8, 0);
|
||||||
tempBuffer += dataSize;
|
tempBuffer += dataSize;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < 90; i++) {
|
for (i = 0; i < 90; i++) {
|
||||||
gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 8, 8);
|
gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 8, 8);
|
||||||
generateMask(textTable[i][0], textTable[i][1], 8 * 8, 0);
|
generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 8 * 8, 0);
|
||||||
tempBuffer += 0x40;
|
tempBuffer += 0x40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,10 @@ namespace Cine {
|
||||||
typedef char CommandeType[20];
|
typedef char CommandeType[20];
|
||||||
|
|
||||||
extern byte *textDataPtr;
|
extern byte *textDataPtr;
|
||||||
extern byte textTable[256][2][16 * 8];
|
|
||||||
|
struct TextHandler {
|
||||||
|
byte textTable[256][2][16 * 8];
|
||||||
|
};
|
||||||
|
|
||||||
extern const char **failureMessages;
|
extern const char **failureMessages;
|
||||||
extern const CommandeType *defaultActionCommand;
|
extern const CommandeType *defaultActionCommand;
|
||||||
|
|
|
@ -464,17 +464,26 @@ bool CineEngine::makeLoad(char *saveName) {
|
||||||
|
|
||||||
broken = brokenSave(*fHandle);
|
broken = brokenSave(*fHandle);
|
||||||
|
|
||||||
|
// At savefile position 0x0000:
|
||||||
currentDisk = fHandle->readUint16BE();
|
currentDisk = fHandle->readUint16BE();
|
||||||
|
|
||||||
|
// At 0x0002:
|
||||||
fHandle->read(currentPartName, 13);
|
fHandle->read(currentPartName, 13);
|
||||||
|
// At 0x000F:
|
||||||
fHandle->read(currentDatName, 13);
|
fHandle->read(currentDatName, 13);
|
||||||
|
|
||||||
|
// At 0x001C:
|
||||||
saveVar2 = fHandle->readSint16BE();
|
saveVar2 = fHandle->readSint16BE();
|
||||||
|
|
||||||
|
// At 0x001E:
|
||||||
fHandle->read(currentPrcName, 13);
|
fHandle->read(currentPrcName, 13);
|
||||||
|
// At 0x002B:
|
||||||
fHandle->read(currentRelName, 13);
|
fHandle->read(currentRelName, 13);
|
||||||
|
// At 0x0038:
|
||||||
fHandle->read(currentMsgName, 13);
|
fHandle->read(currentMsgName, 13);
|
||||||
|
// At 0x0045:
|
||||||
fHandle->read(bgName, 13);
|
fHandle->read(bgName, 13);
|
||||||
|
// At 0x0052:
|
||||||
fHandle->read(currentCtName, 13);
|
fHandle->read(currentCtName, 13);
|
||||||
|
|
||||||
checkDataDisk(currentDisk);
|
checkDataDisk(currentDisk);
|
||||||
|
@ -499,52 +508,84 @@ bool CineEngine::makeLoad(char *saveName) {
|
||||||
loadCtFW(currentCtName);
|
loadCtFW(currentCtName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At 0x005F:
|
||||||
fHandle->readUint16BE();
|
fHandle->readUint16BE();
|
||||||
|
// At 0x0061:
|
||||||
fHandle->readUint16BE();
|
fHandle->readUint16BE();
|
||||||
|
|
||||||
|
// At 0x0063:
|
||||||
for (i = 0; i < 255; i++) {
|
for (i = 0; i < 255; i++) {
|
||||||
|
// At 0x0063 + i * 32 + 0:
|
||||||
objectTable[i].x = fHandle->readSint16BE();
|
objectTable[i].x = fHandle->readSint16BE();
|
||||||
|
// At 0x0063 + i * 32 + 2:
|
||||||
objectTable[i].y = fHandle->readSint16BE();
|
objectTable[i].y = fHandle->readSint16BE();
|
||||||
|
// At 0x0063 + i * 32 + 4:
|
||||||
objectTable[i].mask = fHandle->readUint16BE();
|
objectTable[i].mask = fHandle->readUint16BE();
|
||||||
|
// At 0x0063 + i * 32 + 6:
|
||||||
objectTable[i].frame = fHandle->readSint16BE();
|
objectTable[i].frame = fHandle->readSint16BE();
|
||||||
|
// At 0x0063 + i * 32 + 8:
|
||||||
objectTable[i].costume = fHandle->readSint16BE();
|
objectTable[i].costume = fHandle->readSint16BE();
|
||||||
|
// At 0x0063 + i * 32 + 10:
|
||||||
fHandle->read(objectTable[i].name, 20);
|
fHandle->read(objectTable[i].name, 20);
|
||||||
|
// At 0x0063 + i * 32 + 30:
|
||||||
objectTable[i].part = fHandle->readUint16BE();
|
objectTable[i].part = fHandle->readUint16BE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At 0x2043 (i.e. 0x0063 + 255 * 32):
|
||||||
renderer->restorePalette(*fHandle);
|
renderer->restorePalette(*fHandle);
|
||||||
|
|
||||||
|
// At 0x2083 (i.e. 0x2043 + 16 * 2 * 2):
|
||||||
globalVars.load(*fHandle, NUM_MAX_VAR - 1);
|
globalVars.load(*fHandle, NUM_MAX_VAR - 1);
|
||||||
|
|
||||||
|
// At 0x2281 (i.e. 0x2083 + 255 * 2):
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
|
// At 0x2281 + i * 2:
|
||||||
zoneData[i] = fHandle->readUint16BE();
|
zoneData[i] = fHandle->readUint16BE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At 0x22A1 (i.e. 0x2281 + 16 * 2):
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
// At 0x22A1 + i * 2:
|
||||||
commandVar3[i] = fHandle->readUint16BE();
|
commandVar3[i] = fHandle->readUint16BE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At 0x22A9 (i.e. 0x22A1 + 4 * 2):
|
||||||
fHandle->read(commandBuffer, 0x50);
|
fHandle->read(commandBuffer, 0x50);
|
||||||
renderer->setCommand(commandBuffer);
|
renderer->setCommand(commandBuffer);
|
||||||
|
|
||||||
|
// At 0x22F9 (i.e. 0x22A9 + 0x50):
|
||||||
renderer->_cmdY = fHandle->readUint16BE();
|
renderer->_cmdY = fHandle->readUint16BE();
|
||||||
|
|
||||||
|
// At 0x22FB:
|
||||||
bgVar0 = fHandle->readUint16BE();
|
bgVar0 = fHandle->readUint16BE();
|
||||||
|
// At 0x22FD:
|
||||||
allowPlayerInput = fHandle->readUint16BE();
|
allowPlayerInput = fHandle->readUint16BE();
|
||||||
|
// At 0x22FF:
|
||||||
playerCommand = fHandle->readSint16BE();
|
playerCommand = fHandle->readSint16BE();
|
||||||
|
// At 0x2301:
|
||||||
commandVar1 = fHandle->readSint16BE();
|
commandVar1 = fHandle->readSint16BE();
|
||||||
|
// At 0x2303:
|
||||||
isDrawCommandEnabled = fHandle->readUint16BE();
|
isDrawCommandEnabled = fHandle->readUint16BE();
|
||||||
|
// At 0x2305:
|
||||||
var5 = fHandle->readUint16BE();
|
var5 = fHandle->readUint16BE();
|
||||||
|
// At 0x2307:
|
||||||
var4 = fHandle->readUint16BE();
|
var4 = fHandle->readUint16BE();
|
||||||
|
// At 0x2309:
|
||||||
var3 = fHandle->readUint16BE();
|
var3 = fHandle->readUint16BE();
|
||||||
|
// At 0x230B:
|
||||||
var2 = fHandle->readUint16BE();
|
var2 = fHandle->readUint16BE();
|
||||||
|
// At 0x230D:
|
||||||
commandVar2 = fHandle->readSint16BE();
|
commandVar2 = fHandle->readSint16BE();
|
||||||
|
|
||||||
|
// At 0x230F:
|
||||||
renderer->_messageBg = fHandle->readUint16BE();
|
renderer->_messageBg = fHandle->readUint16BE();
|
||||||
|
|
||||||
|
// At 0x2311:
|
||||||
fHandle->readUint16BE();
|
fHandle->readUint16BE();
|
||||||
|
// At 0x2313:
|
||||||
fHandle->readUint16BE();
|
fHandle->readUint16BE();
|
||||||
|
|
||||||
|
// At 0x2315:
|
||||||
loadResourcesFromSave(*fHandle, broken);
|
loadResourcesFromSave(*fHandle, broken);
|
||||||
|
|
||||||
// TODO: handle screen params (really required ?)
|
// TODO: handle screen params (really required ?)
|
||||||
|
@ -1516,12 +1557,22 @@ void mainLoopSub6(void) {
|
||||||
|
|
||||||
void checkForPendingDataLoad(void) {
|
void checkForPendingDataLoad(void) {
|
||||||
if (newPrcName[0] != 0) {
|
if (newPrcName[0] != 0) {
|
||||||
loadPrc(newPrcName);
|
bool loadPrcOk = loadPrc(newPrcName);
|
||||||
|
|
||||||
strcpy(currentPrcName, newPrcName);
|
strcpy(currentPrcName, newPrcName);
|
||||||
strcpy(newPrcName, "");
|
strcpy(newPrcName, "");
|
||||||
|
|
||||||
addScriptToList0(1);
|
// Check that the loading of the script file was successful before
|
||||||
|
// trying to add script 1 from it to the global scripts list. This
|
||||||
|
// fixes a crash when failing copy protection in Amiga or Atari ST
|
||||||
|
// versions of Future Wars.
|
||||||
|
if (loadPrcOk) {
|
||||||
|
addScriptToList0(1);
|
||||||
|
} else if (scumm_stricmp(currentPrcName, COPY_PROT_FAIL_PRC_NAME)) {
|
||||||
|
// We only show an error here for other files than the file that
|
||||||
|
// is loaded if copy protection fails (i.e. L201.ANI).
|
||||||
|
warning("checkForPendingDataLoad: loadPrc(%s) failed", currentPrcName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newRelName[0] != 0) {
|
if (newRelName[0] != 0) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ int KyraEngine_v1::init() {
|
||||||
_sound = new SoundTownsPC98_v2(this, _mixer);
|
_sound = new SoundTownsPC98_v2(this, _mixer);
|
||||||
} else if (_flags.platform == Common::kPlatformPC98) {
|
} else if (_flags.platform == Common::kPlatformPC98) {
|
||||||
if (_flags.gameID == GI_KYRA1)
|
if (_flags.gameID == GI_KYRA1)
|
||||||
_sound = new SoundPC98(this, _mixer);
|
_sound = new SoundTowns/*SoundPC98*/(this, _mixer);
|
||||||
else
|
else
|
||||||
_sound = new SoundTownsPC98_v2(this, _mixer);
|
_sound = new SoundTownsPC98_v2(this, _mixer);
|
||||||
} else if (midiDriver == MD_ADLIB) {
|
} else if (midiDriver == MD_ADLIB) {
|
||||||
|
|
|
@ -2363,7 +2363,7 @@ TownsPC98_OpnDriver::TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type) :
|
||||||
_numSSG(type == OD_TOWNS ? 0 : 3), _hasADPCM(type == OD_TYPE86 ? true : false),
|
_numSSG(type == OD_TOWNS ? 0 : 3), _hasADPCM(type == OD_TYPE86 ? true : false),
|
||||||
_numChan(type == OD_TYPE26 ? 3 : 6), _hasStereo(type == OD_TYPE26 ? false : true) {
|
_numChan(type == OD_TYPE26 ? 3 : 6), _hasStereo(type == OD_TYPE26 ? false : true) {
|
||||||
setTempo(84);
|
setTempo(84);
|
||||||
_baserate = (3579545.0 / (double)getRate()) / 144.0;
|
_baserate = (double)getRate() / 10368.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TownsPC98_OpnDriver::~TownsPC98_OpnDriver() {
|
TownsPC98_OpnDriver::~TownsPC98_OpnDriver() {
|
||||||
|
@ -3095,8 +3095,8 @@ SoundTownsPC98_v2::~SoundTownsPC98_v2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundTownsPC98_v2::init() {
|
bool SoundTownsPC98_v2::init() {
|
||||||
_driver = new TownsPC98_OpnDriver(_mixer, _vm->gameFlags().platform == Common::kPlatformPC98 ?
|
_driver = new TownsPC98_OpnDriver(_mixer, /*_vm->gameFlags().platform == Common::kPlatformPC98 ?
|
||||||
TownsPC98_OpnDriver::OD_TYPE86 : TownsPC98_OpnDriver::OD_TOWNS);
|
TownsPC98_OpnDriver::OD_TYPE86 :*/ TownsPC98_OpnDriver::OD_TOWNS);
|
||||||
_useFmSfx = _vm->gameFlags().platform == Common::kPlatformPC98 ? true : false;
|
_useFmSfx = _vm->gameFlags().platform == Common::kPlatformPC98 ? true : false;
|
||||||
_vm->checkCD();
|
_vm->checkCD();
|
||||||
// FIXME: While checking for 'track1.XXX(X)' looks like
|
// FIXME: While checking for 'track1.XXX(X)' looks like
|
||||||
|
|
|
@ -1034,8 +1034,10 @@ void KyraEngine_LoK::initStaticResource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// audio data tables
|
// audio data tables
|
||||||
|
#if 0
|
||||||
static const char *tIntro98[] = { "intro%d.dat" };
|
static const char *tIntro98[] = { "intro%d.dat" };
|
||||||
static const char *tIngame98[] = { "kyram%d.dat" };
|
static const char *tIngame98[] = { "kyram%d.dat" };
|
||||||
|
#endif
|
||||||
|
|
||||||
static const AudioDataStruct soundData_PC[] = {
|
static const AudioDataStruct soundData_PC[] = {
|
||||||
{ _soundFilesIntro, _soundFilesIntroSize, 0, 0 },
|
{ _soundFilesIntro, _soundFilesIntroSize, 0, 0 },
|
||||||
|
@ -1049,18 +1051,20 @@ void KyraEngine_LoK::initStaticResource() {
|
||||||
{ 0, 0, 0, 0}
|
{ 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
static const AudioDataStruct soundData_PC98[] = {
|
static const AudioDataStruct soundData_PC98[] = {
|
||||||
{ tIntro98, 1, 0, 0 },
|
{ tIntro98, 1, 0, 0 },
|
||||||
{ tIngame98, 1, 0, 0 },
|
{ tIngame98, 1, 0, 0 },
|
||||||
{ 0, 0, 0, 0}
|
{ 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_flags.platform == Common::kPlatformPC)
|
if (_flags.platform == Common::kPlatformPC)
|
||||||
_soundData = soundData_PC;
|
_soundData = soundData_PC;
|
||||||
else if (_flags.platform == Common::kPlatformFMTowns)
|
else if (_flags.platform == Common::kPlatformFMTowns)
|
||||||
_soundData = soundData_TOWNS;
|
_soundData = soundData_TOWNS;
|
||||||
else if (_flags.platform == Common::kPlatformPC98)
|
else if (_flags.platform == Common::kPlatformPC98)
|
||||||
_soundData = soundData_PC98;
|
_soundData = soundData_TOWNS/*soundData_PC98*/;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,9 +1263,11 @@ void KyraEngine_HoF::initStaticResource() {
|
||||||
static const char *fmtMusicFileListFinale[] = { "finale%d.twn" };
|
static const char *fmtMusicFileListFinale[] = { "finale%d.twn" };
|
||||||
static const char *fmtMusicFileListIngame[] = { "km%02d.twn" };
|
static const char *fmtMusicFileListIngame[] = { "km%02d.twn" };
|
||||||
|
|
||||||
|
#if 0
|
||||||
static const char *pc98MusicFileListIntro[] = { "intro%d.86" };
|
static const char *pc98MusicFileListIntro[] = { "intro%d.86" };
|
||||||
static const char *pc98MusicFileListFinale[] = { "finale%d.86" };
|
static const char *pc98MusicFileListFinale[] = { "finale%d.86" };
|
||||||
static const char *pc98MusicFileListIngame[] = { "km%02d.86" };
|
static const char *pc98MusicFileListIngame[] = { "km%02d.86" };
|
||||||
|
#endif
|
||||||
|
|
||||||
static const AudioDataStruct soundData_PC[] = {
|
static const AudioDataStruct soundData_PC[] = {
|
||||||
{ _musicFileListIntro, _musicFileListIntroSize, 0, 0 },
|
{ _musicFileListIntro, _musicFileListIntroSize, 0, 0 },
|
||||||
|
@ -1275,18 +1281,20 @@ void KyraEngine_HoF::initStaticResource() {
|
||||||
{ fmtMusicFileListFinale, 1, _cdaTrackTableFinale, _cdaTrackTableFinaleSize >> 1 }
|
{ fmtMusicFileListFinale, 1, _cdaTrackTableFinale, _cdaTrackTableFinaleSize >> 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
static const AudioDataStruct soundData_PC98[] = {
|
static const AudioDataStruct soundData_PC98[] = {
|
||||||
{ pc98MusicFileListIntro, 1, 0, 0 },
|
{ pc98MusicFileListIntro, 1, 0, 0 },
|
||||||
{ pc98MusicFileListIngame, 1, 0, 0 },
|
{ pc98MusicFileListIngame, 1, 0, 0 },
|
||||||
{ pc98MusicFileListFinale, 1, 0, 0 }
|
{ pc98MusicFileListFinale, 1, 0, 0 }
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_flags.platform == Common::kPlatformPC)
|
if (_flags.platform == Common::kPlatformPC)
|
||||||
_soundData = soundData_PC;
|
_soundData = soundData_PC;
|
||||||
else if (_flags.platform == Common::kPlatformFMTowns)
|
else if (_flags.platform == Common::kPlatformFMTowns)
|
||||||
_soundData = soundData_TOWNS;
|
_soundData = soundData_TOWNS;
|
||||||
else if (_flags.platform == Common::kPlatformPC98)
|
else if (_flags.platform == Common::kPlatformPC98)
|
||||||
_soundData = soundData_PC98;
|
_soundData = soundData_TOWNS/*soundData_PC98*/;
|
||||||
|
|
||||||
// setup sequence data
|
// setup sequence data
|
||||||
_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);
|
_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace Lure {
|
||||||
#define LURE_DAT_MAJOR 1
|
#define LURE_DAT_MAJOR 1
|
||||||
#define LURE_DAT_MINOR 29
|
#define LURE_DAT_MINOR 29
|
||||||
#define LURE_MIN_SAVEGAME_MINOR 25
|
#define LURE_MIN_SAVEGAME_MINOR 25
|
||||||
#define LURE_SAVEGAME_MINOR 32
|
#define LURE_SAVEGAME_MINOR 33
|
||||||
|
|
||||||
#define LURE_DEBUG 1
|
#define LURE_DEBUG 1
|
||||||
|
|
||||||
|
|
|
@ -456,6 +456,8 @@ void HotspotData::saveToStream(WriteStream *stream) {
|
||||||
stream->writeSint16LE(startY);
|
stream->writeSint16LE(startY);
|
||||||
stream->writeUint16LE(roomNumber);
|
stream->writeUint16LE(roomNumber);
|
||||||
stream->writeByte(layer);
|
stream->writeByte(layer);
|
||||||
|
stream->writeUint16LE(walkX);
|
||||||
|
stream->writeUint16LE(walkY);
|
||||||
|
|
||||||
stream->writeUint16LE(width);
|
stream->writeUint16LE(width);
|
||||||
stream->writeUint16LE(height);
|
stream->writeUint16LE(height);
|
||||||
|
@ -503,6 +505,10 @@ void HotspotData::loadFromStream(ReadStream *stream) {
|
||||||
uint8 saveVersion = LureEngine::getReference().saveVersion();
|
uint8 saveVersion = LureEngine::getReference().saveVersion();
|
||||||
if (saveVersion >= 29)
|
if (saveVersion >= 29)
|
||||||
layer = stream->readByte();
|
layer = stream->readByte();
|
||||||
|
if (saveVersion >= 33) {
|
||||||
|
walkX = stream->readUint16LE();
|
||||||
|
walkY = stream->readUint16LE();
|
||||||
|
}
|
||||||
|
|
||||||
width = stream->readUint16LE();
|
width = stream->readUint16LE();
|
||||||
height = stream->readUint16LE();
|
height = stream->readUint16LE();
|
||||||
|
|
|
@ -424,6 +424,7 @@ void Parallaction_ns::_c_testResult(void *parm) {
|
||||||
}
|
}
|
||||||
_inTestResult = true;
|
_inTestResult = true;
|
||||||
|
|
||||||
|
_gfx->freeLabels();
|
||||||
_gfx->updateScreen();
|
_gfx->updateScreen();
|
||||||
|
|
||||||
_disk->selectArchive("disk1");
|
_disk->selectArchive("disk1");
|
||||||
|
|
|
@ -42,13 +42,23 @@ namespace Parallaction {
|
||||||
#define ANSWER_CHARACTER_X 10
|
#define ANSWER_CHARACTER_X 10
|
||||||
#define ANSWER_CHARACTER_Y 80
|
#define ANSWER_CHARACTER_Y 80
|
||||||
|
|
||||||
|
|
||||||
class DialogueManager {
|
class DialogueManager {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RUN_QUESTION,
|
||||||
|
RUN_ANSWER,
|
||||||
|
NEXT_QUESTION,
|
||||||
|
NEXT_ANSWER,
|
||||||
|
DIALOGUE_OVER
|
||||||
|
} _state;
|
||||||
|
|
||||||
Parallaction *_vm;
|
Parallaction *_vm;
|
||||||
SpeakData *_data;
|
|
||||||
Dialogue *_dialogue;
|
Dialogue *_dialogue;
|
||||||
|
|
||||||
bool _askPassword;
|
bool _askPassword;
|
||||||
|
int _passwordLen;
|
||||||
|
bool _passwordChanged;
|
||||||
|
|
||||||
bool isNpc;
|
bool isNpc;
|
||||||
GfxObj *_questioner;
|
GfxObj *_questioner;
|
||||||
|
@ -59,92 +69,69 @@ class DialogueManager {
|
||||||
uint16 _visAnswers[5];
|
uint16 _visAnswers[5];
|
||||||
int _numVisAnswers;
|
int _numVisAnswers;
|
||||||
|
|
||||||
|
int _answerId;
|
||||||
|
|
||||||
|
int _selection, _oldSelection;
|
||||||
|
|
||||||
|
uint32 _mouseButtons;
|
||||||
|
Common::Point _mousePos;
|
||||||
|
bool _isKeyDown;
|
||||||
|
uint16 _downKey;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) {
|
DialogueManager(Parallaction *vm, ZonePtr z);
|
||||||
_dialogue = _data->_dialogue;
|
~DialogueManager();
|
||||||
isNpc = scumm_stricmp(_data->_name, "yourself") && _data->_name[0] != '\0';
|
|
||||||
_questioner = isNpc ? _vm->_disk->loadTalk(_data->_name) : _vm->_char._talk;
|
|
||||||
_answerer = _vm->_char._talk;
|
|
||||||
}
|
|
||||||
|
|
||||||
~DialogueManager() {
|
bool isOver() {
|
||||||
if (isNpc) {
|
return _state == DIALOGUE_OVER;
|
||||||
delete _questioner;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
ZonePtr _z;
|
||||||
|
CommandList *_cmdList;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void displayQuestion();
|
bool displayQuestion();
|
||||||
bool displayAnswers();
|
bool displayAnswers();
|
||||||
bool displayAnswer(uint16 i);
|
bool displayAnswer(uint16 i);
|
||||||
|
|
||||||
uint16 getAnswer();
|
int16 selectAnswer1();
|
||||||
int16 selectAnswer();
|
int16 selectAnswerN();
|
||||||
uint16 askPassword();
|
int16 askPassword();
|
||||||
int16 getHoverAnswer(int16 x, int16 y);
|
int16 getHoverAnswer(int16 x, int16 y);
|
||||||
|
|
||||||
|
void runQuestion();
|
||||||
|
void runAnswer();
|
||||||
|
void nextQuestion();
|
||||||
|
void nextAnswer();
|
||||||
|
|
||||||
|
bool checkPassword();
|
||||||
|
void resetPassword();
|
||||||
|
void accumPassword(uint16 ascii);
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16 DialogueManager::askPassword() {
|
DialogueManager::DialogueManager(Parallaction *vm, ZonePtr z) : _vm(vm), _z(z) {
|
||||||
debugC(3, kDebugExec, "checkDialoguePassword()");
|
_dialogue = _z->u.speak->_dialogue;
|
||||||
|
isNpc = scumm_stricmp(_z->u.speak->_name, "yourself") && _z->u.speak->_name[0] != '\0';
|
||||||
|
_questioner = isNpc ? _vm->_disk->loadTalk(_z->u.speak->_name) : _vm->_char._talk;
|
||||||
|
_answerer = _vm->_char._talk;
|
||||||
|
|
||||||
uint16 passwordLen = 0;
|
_askPassword = false;
|
||||||
_password[0] = '\0';
|
_q = _dialogue->_questions[0];
|
||||||
|
|
||||||
_vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
|
_cmdList = 0;
|
||||||
int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
|
_answerId = 0;
|
||||||
_vm->_gfx->setItemFrame(id, 0);
|
|
||||||
|
|
||||||
Common::Event e;
|
|
||||||
bool changed = true; // force first refresh
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
e.kbd.ascii = 0;
|
|
||||||
|
|
||||||
if (g_system->getEventManager()->pollEvent(e)) {
|
|
||||||
if ((e.type == Common::EVENT_KEYDOWN) && isdigit(e.kbd.ascii)) {
|
|
||||||
_password[passwordLen] = e.kbd.ascii;
|
|
||||||
passwordLen++;
|
|
||||||
_password[passwordLen] = '\0';
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
|
|
||||||
_vm->_gfx->updateScreen();
|
|
||||||
changed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((passwordLen == MAX_PASSWORD_LENGTH) || (e.kbd.ascii == Common::KEYCODE_RETURN)) {
|
|
||||||
|
|
||||||
if ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
|
|
||||||
(!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
|
|
||||||
(!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))) {
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
passwordLen = 0;
|
|
||||||
_password[0] = '\0';
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
g_system->delayMillis(20);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_vm->hideDialogueStuff();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
_state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DialogueManager::~DialogueManager() {
|
||||||
|
if (isNpc) {
|
||||||
|
delete _questioner;
|
||||||
|
}
|
||||||
|
_z = nullZonePtr;
|
||||||
|
}
|
||||||
|
|
||||||
bool DialogueManager::displayAnswer(uint16 i) {
|
bool DialogueManager::displayAnswer(uint16 i) {
|
||||||
|
|
||||||
|
@ -161,7 +148,7 @@ bool DialogueManager::displayAnswer(uint16 i) {
|
||||||
assert(id >= 0);
|
assert(id >= 0);
|
||||||
_visAnswers[id] = i;
|
_visAnswers[id] = i;
|
||||||
|
|
||||||
_askPassword = (strstr(a->_text, "%p") != NULL);
|
_askPassword = (strstr(a->_text, "%P") != NULL);
|
||||||
_numVisAnswers++;
|
_numVisAnswers++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -178,134 +165,244 @@ bool DialogueManager::displayAnswers() {
|
||||||
displayAnswer(i);
|
displayAnswer(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_askPassword) {
|
||||||
|
resetPassword();
|
||||||
|
// _vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
|
||||||
|
int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
|
||||||
|
_vm->_gfx->setItemFrame(id, 0);
|
||||||
|
} else
|
||||||
|
if (_numVisAnswers == 1) {
|
||||||
|
int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
|
||||||
|
_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
|
||||||
|
_vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text, 0);
|
||||||
|
} else
|
||||||
|
if (_numVisAnswers > 1) {
|
||||||
|
int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
|
||||||
|
_vm->_gfx->setItemFrame(id, _q->_answers[_visAnswers[0]]->_mood & 0xF);
|
||||||
|
_oldSelection = -1;
|
||||||
|
_selection = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return _numVisAnswers > 0;
|
return _numVisAnswers > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::displayQuestion() {
|
bool DialogueManager::displayQuestion() {
|
||||||
|
if (!scumm_stricmp(_q->_text, "NULL")) return false;
|
||||||
if (!scumm_stricmp(_q->_text, "NULL")) return;
|
|
||||||
|
|
||||||
_vm->_balloonMan->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0);
|
_vm->_balloonMan->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0);
|
||||||
int id = _vm->_gfx->setItem(_questioner, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y);
|
int id = _vm->_gfx->setItem(_questioner, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y);
|
||||||
_vm->_gfx->setItemFrame(id, _q->_mood & 0xF);
|
_vm->_gfx->setItemFrame(id, _q->_mood & 0xF);
|
||||||
|
|
||||||
_vm->_gfx->updateScreen();
|
return true;
|
||||||
_vm->_input->waitUntilLeftClick();
|
|
||||||
_vm->hideDialogueStuff();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 DialogueManager::getAnswer() {
|
|
||||||
|
|
||||||
uint16 answer = 0;
|
bool DialogueManager::checkPassword() {
|
||||||
|
return ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
|
||||||
|
(!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
|
||||||
|
(!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3)));
|
||||||
|
}
|
||||||
|
|
||||||
if (_askPassword == false) {
|
void DialogueManager::resetPassword() {
|
||||||
answer = selectAnswer();
|
_passwordLen = 0;
|
||||||
} else {
|
_password[0] = '\0';
|
||||||
answer = askPassword();
|
_passwordChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueManager::accumPassword(uint16 ascii) {
|
||||||
|
if (!isdigit(ascii)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugC(3, kDebugExec, "runDialogue: user selected answer #%i", answer);
|
_password[_passwordLen] = ascii;
|
||||||
|
_passwordLen++;
|
||||||
|
_password[_passwordLen] = '\0';
|
||||||
|
_passwordChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
return answer;
|
int16 DialogueManager::askPassword() {
|
||||||
|
|
||||||
|
if (_isKeyDown) {
|
||||||
|
accumPassword(_downKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_passwordChanged) {
|
||||||
|
_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
|
||||||
|
_passwordChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_passwordLen == MAX_PASSWORD_LENGTH) || ((_isKeyDown) && (_downKey == Common::KEYCODE_RETURN))) {
|
||||||
|
if (checkPassword()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
resetPassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 DialogueManager::selectAnswer1() {
|
||||||
|
|
||||||
|
if (_mouseButtons == kMouseLeftUp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 DialogueManager::selectAnswerN() {
|
||||||
|
|
||||||
|
_selection = _vm->_balloonMan->hitTestDialogueBalloon(_mousePos.x, _mousePos.y);
|
||||||
|
|
||||||
|
if (_selection != _oldSelection) {
|
||||||
|
if (_oldSelection != -1) {
|
||||||
|
_vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vm->quit())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (_selection != -1) {
|
||||||
|
_vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, 0);
|
||||||
|
_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[_selection]]->_mood & 0xF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_oldSelection = _selection;
|
||||||
|
|
||||||
|
if ((_mouseButtons == kMouseLeftUp) && (_selection != -1)) {
|
||||||
|
return _visAnswers[_selection];
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueManager::runQuestion() {
|
||||||
|
debugC(9, kDebugDialogue, "runQuestion\n");
|
||||||
|
|
||||||
|
if (_mouseButtons == kMouseLeftUp) {
|
||||||
|
_vm->hideDialogueStuff();
|
||||||
|
_state = NEXT_ANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DialogueManager::nextAnswer() {
|
||||||
|
debugC(9, kDebugDialogue, "nextAnswer\n");
|
||||||
|
|
||||||
|
if (_q->_answers[0] == NULL) {
|
||||||
|
_state = DIALOGUE_OVER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
|
||||||
|
_answerId = 0;
|
||||||
|
_state = NEXT_QUESTION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = displayAnswers() ? RUN_ANSWER : DIALOGUE_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueManager::runAnswer() {
|
||||||
|
debugC(9, kDebugDialogue, "runAnswer\n");
|
||||||
|
|
||||||
|
if (_askPassword) {
|
||||||
|
_answerId = askPassword();
|
||||||
|
} else
|
||||||
|
if (_numVisAnswers == 1) {
|
||||||
|
_answerId = selectAnswer1();
|
||||||
|
} else {
|
||||||
|
_answerId = selectAnswerN();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_answerId != -1) {
|
||||||
|
_cmdList = &_q->_answers[_answerId]->_commands;
|
||||||
|
_vm->hideDialogueStuff();
|
||||||
|
_state = NEXT_QUESTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueManager::nextQuestion() {
|
||||||
|
debugC(9, kDebugDialogue, "nextQuestion\n");
|
||||||
|
|
||||||
|
_q = _q->_answers[_answerId]->_following._question;
|
||||||
|
if (_q == 0) {
|
||||||
|
_state = DIALOGUE_OVER;
|
||||||
|
} else {
|
||||||
|
_state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::run() {
|
void DialogueManager::run() {
|
||||||
|
|
||||||
_askPassword = false;
|
// cache event data
|
||||||
CommandList *cmdlist = NULL;
|
_mouseButtons = _vm->_input->getLastButtonEvent();
|
||||||
|
_vm->_input->getCursorPos(_mousePos);
|
||||||
|
_isKeyDown = _vm->_input->getLastKeyDown(_downKey);
|
||||||
|
|
||||||
_q = _dialogue->_questions[0];
|
switch (_state) {
|
||||||
int16 answer;
|
case RUN_QUESTION:
|
||||||
|
runQuestion();
|
||||||
|
break;
|
||||||
|
|
||||||
while (_q) {
|
case NEXT_ANSWER:
|
||||||
|
nextAnswer();
|
||||||
|
break;
|
||||||
|
|
||||||
answer = 0;
|
case NEXT_QUESTION:
|
||||||
|
nextQuestion();
|
||||||
|
break;
|
||||||
|
|
||||||
displayQuestion();
|
case RUN_ANSWER:
|
||||||
|
runAnswer();
|
||||||
|
break;
|
||||||
|
|
||||||
if (_vm->quit())
|
case DIALOGUE_OVER:
|
||||||
return;
|
if (_cmdList) {
|
||||||
|
_vm->_cmdExec->run(*_cmdList);
|
||||||
if (_q->_answers[0] == NULL) break;
|
|
||||||
|
|
||||||
if (scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
|
|
||||||
if (!displayAnswers()) break;
|
|
||||||
answer = getAnswer();
|
|
||||||
|
|
||||||
if (_vm->quit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
cmdlist = &_q->_answers[answer]->_commands;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("unknown state in DialogueManager");
|
||||||
|
|
||||||
_q = _q->_answers[answer]->_following._question;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdlist)
|
|
||||||
_vm->_cmdExec->run(*cmdlist);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 DialogueManager::selectAnswer() {
|
void Parallaction::enterDialogueMode(ZonePtr z) {
|
||||||
|
debugC(1, kDebugDialogue, "Parallaction::enterDialogueMode(%s)", z->u.speak->_name);
|
||||||
int16 numAvailableAnswers = _numVisAnswers;
|
_dialogueMan = new DialogueManager(this, z);
|
||||||
|
_input->_inputMode = Input::kInputModeDialogue;
|
||||||
int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
|
|
||||||
_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
|
|
||||||
|
|
||||||
if (numAvailableAnswers == 1) {
|
|
||||||
_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 0);
|
|
||||||
_vm->_input->waitUntilLeftClick();
|
|
||||||
_vm->hideDialogueStuff();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int oldSelection = -1;
|
|
||||||
int selection = 0;
|
|
||||||
|
|
||||||
uint32 event;
|
|
||||||
Common::Point p;
|
|
||||||
while (!_vm->quit()) {
|
|
||||||
|
|
||||||
_vm->_input->readInput();
|
|
||||||
_vm->_input->getCursorPos(p);
|
|
||||||
event = _vm->_input->getLastButtonEvent();
|
|
||||||
selection = _vm->_balloonMan->hitTestDialogueBalloon(p.x, p.y);
|
|
||||||
|
|
||||||
if (selection != oldSelection) {
|
|
||||||
if (oldSelection != -1) {
|
|
||||||
_vm->_balloonMan->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection != -1) {
|
|
||||||
_vm->_balloonMan->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0);
|
|
||||||
_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((selection != -1) && (event == kMouseLeftUp)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_vm->_gfx->updateScreen();
|
|
||||||
g_system->delayMillis(20);
|
|
||||||
|
|
||||||
oldSelection = selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
_vm->hideDialogueStuff();
|
|
||||||
|
|
||||||
return _visAnswers[selection];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parallaction::exitDialogueMode() {
|
||||||
|
debugC(1, kDebugDialogue, "Parallaction::exitDialogueMode()");
|
||||||
|
_input->_inputMode = Input::kInputModeGame;
|
||||||
|
|
||||||
void Parallaction::runDialogue(SpeakData *data) {
|
// The current instance of _dialogueMan must be destroyed before the zone commands
|
||||||
debugC(1, kDebugExec, "runDialogue: starting dialogue '%s'", data->_name);
|
// are executed, because they may create another instance of _dialogueMan that
|
||||||
|
// overwrite the current one. This would cause headaches (and it did, actually).
|
||||||
|
ZonePtr z = _dialogueMan->_z;
|
||||||
|
delete _dialogueMan;
|
||||||
|
_dialogueMan = 0;
|
||||||
|
|
||||||
DialogueManager man(this, data);
|
_cmdExec->run(z->_commands, z);
|
||||||
man.run();
|
}
|
||||||
|
|
||||||
|
void Parallaction::runDialogueFrame() {
|
||||||
|
if (_input->_inputMode != Input::kInputModeDialogue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dialogueMan->run();
|
||||||
|
|
||||||
|
if (_dialogueMan->isOver()) {
|
||||||
|
exitDialogueMode();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,11 @@ DECLARE_COMMAND_OPCODE(start) {
|
||||||
|
|
||||||
|
|
||||||
DECLARE_COMMAND_OPCODE(speak) {
|
DECLARE_COMMAND_OPCODE(speak) {
|
||||||
_vm->_activeZone = _ctxt.cmd->u._zone;
|
if ((_ctxt.cmd->u._zone->_type & 0xFFFF) == kZoneSpeak) {
|
||||||
|
_vm->enterDialogueMode(_ctxt.cmd->u._zone);
|
||||||
|
} else {
|
||||||
|
_vm->_activeZone = _ctxt.cmd->u._zone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,6 +326,7 @@ DECLARE_COMMAND_OPCODE(stop) {
|
||||||
|
|
||||||
|
|
||||||
void Parallaction_ns::drawAnimations() {
|
void Parallaction_ns::drawAnimations() {
|
||||||
|
debugC(9, kDebugExec, "Parallaction_ns::drawAnimations()\n");
|
||||||
|
|
||||||
uint16 layer = 0;
|
uint16 layer = 0;
|
||||||
|
|
||||||
|
@ -362,6 +367,8 @@ void Parallaction_ns::drawAnimations() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugC(9, kDebugExec, "Parallaction_ns::drawAnimations done()\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +424,6 @@ label1:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CommandExec::run(CommandList& list, ZonePtr z) {
|
void CommandExec::run(CommandList& list, ZonePtr z) {
|
||||||
if (list.size() == 0) {
|
if (list.size() == 0) {
|
||||||
debugC(3, kDebugExec, "runCommands: nothing to do");
|
debugC(3, kDebugExec, "runCommands: nothing to do");
|
||||||
|
@ -542,11 +548,8 @@ uint16 Parallaction::runZone(ZonePtr z) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kZoneSpeak:
|
case kZoneSpeak:
|
||||||
runDialogue(z->u.speak);
|
enterDialogueMode(z);
|
||||||
if (_vm->quit())
|
return 0;
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debugC(3, kDebugExec, "runZone completed");
|
debugC(3, kDebugExec, "runZone completed");
|
||||||
|
|
|
@ -267,9 +267,6 @@ void Gfx::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this is the maximum size of an unpacked frame in BRA
|
|
||||||
byte _unpackedBitmap[640*401];
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
|
void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
|
|
||||||
namespace Parallaction {
|
namespace Parallaction {
|
||||||
|
|
||||||
|
// this is the size of the receiving buffer for unpacked frames,
|
||||||
|
// since BRA uses some insanely big animations.
|
||||||
|
#define MAXIMUM_UNPACKED_BITMAP_SIZE 640*401
|
||||||
|
|
||||||
|
|
||||||
void Gfx::registerVar(const Common::String &name, int32 initialValue) {
|
void Gfx::registerVar(const Common::String &name, int32 initialValue) {
|
||||||
if (_vars.contains(name)) {
|
if (_vars.contains(name)) {
|
||||||
warning("Variable '%s' already registered, ignoring initial value.\n", name.c_str());
|
warning("Variable '%s' already registered, ignoring initial value.\n", name.c_str());
|
||||||
|
@ -752,6 +757,9 @@ Gfx::Gfx(Parallaction* vm) :
|
||||||
_halfbrite = false;
|
_halfbrite = false;
|
||||||
_hbCircleRadius = 0;
|
_hbCircleRadius = 0;
|
||||||
|
|
||||||
|
_unpackedBitmap = new byte[MAXIMUM_UNPACKED_BITMAP_SIZE];
|
||||||
|
assert(_unpackedBitmap);
|
||||||
|
|
||||||
registerVar("background_mode", 1);
|
registerVar("background_mode", 1);
|
||||||
_varBackgroundMode = 1;
|
_varBackgroundMode = 1;
|
||||||
|
|
||||||
|
@ -769,6 +777,8 @@ Gfx::~Gfx() {
|
||||||
freeBackground();
|
freeBackground();
|
||||||
freeLabels();
|
freeLabels();
|
||||||
|
|
||||||
|
delete []_unpackedBitmap;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,6 +547,8 @@ public:
|
||||||
uint _screenX; // scrolling position
|
uint _screenX; // scrolling position
|
||||||
uint _screenY;
|
uint _screenY;
|
||||||
|
|
||||||
|
byte *_unpackedBitmap;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Parallaction* _vm;
|
Parallaction* _vm;
|
||||||
bool _halfbrite;
|
bool _halfbrite;
|
||||||
|
|
|
@ -42,12 +42,14 @@ uint16 Input::readInput() {
|
||||||
uint16 KeyDown = 0;
|
uint16 KeyDown = 0;
|
||||||
|
|
||||||
_mouseButtons = kMouseNone;
|
_mouseButtons = kMouseNone;
|
||||||
|
_lastKeyDownAscii = -1;
|
||||||
|
|
||||||
Common::EventManager *eventMan = _vm->_system->getEventManager();
|
Common::EventManager *eventMan = _vm->_system->getEventManager();
|
||||||
while (eventMan->pollEvent(e)) {
|
while (eventMan->pollEvent(e)) {
|
||||||
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case Common::EVENT_KEYDOWN:
|
case Common::EVENT_KEYDOWN:
|
||||||
|
_lastKeyDownAscii = e.kbd.ascii;
|
||||||
if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd')
|
if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd')
|
||||||
_vm->_debugger->attach();
|
_vm->_debugger->attach();
|
||||||
if (_vm->getFeatures() & GF_DEMO) break;
|
if (_vm->getFeatures() & GF_DEMO) break;
|
||||||
|
@ -97,6 +99,11 @@ uint16 Input::readInput() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Input::getLastKeyDown(uint16 &ascii) {
|
||||||
|
ascii = _lastKeyDownAscii;
|
||||||
|
return (_lastKeyDownAscii != -1);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: see comment for readInput()
|
// FIXME: see comment for readInput()
|
||||||
void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) {
|
void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) {
|
||||||
|
|
||||||
|
@ -192,11 +199,38 @@ InputData* Input::updateInput() {
|
||||||
case kInputModeGame:
|
case kInputModeGame:
|
||||||
updateGameInput();
|
updateGameInput();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kInputModeDialogue:
|
||||||
|
readInput();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &_inputData;
|
return &_inputData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Input::trackMouse(ZonePtr z) {
|
||||||
|
if ((z != _hoverZone) && (_hoverZone)) {
|
||||||
|
stopHovering();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!z) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) {
|
||||||
|
_hoverZone = z;
|
||||||
|
_vm->_gfx->showFloatingLabel(_hoverZone->_label);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::stopHovering() {
|
||||||
|
_hoverZone = nullZonePtr;
|
||||||
|
_vm->_gfx->hideFloatingLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Input::translateGameInput() {
|
bool Input::translateGameInput() {
|
||||||
|
|
||||||
if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) {
|
if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) {
|
||||||
|
@ -231,23 +265,10 @@ bool Input::translateGameInput() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((z != _hoverZone) && (_hoverZone)) {
|
trackMouse(z);
|
||||||
_hoverZone = nullZonePtr;
|
if (!z) {
|
||||||
_inputData._event = kEvExitZone;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!z) {
|
|
||||||
_inputData._event = kEvNone;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) {
|
|
||||||
_hoverZone = z;
|
|
||||||
_inputData._event = kEvEnterZone;
|
|
||||||
_inputData._label = z->_label;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) {
|
if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) {
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ class Input {
|
||||||
|
|
||||||
Common::Point _mousePos;
|
Common::Point _mousePos;
|
||||||
uint16 _mouseButtons;
|
uint16 _mouseButtons;
|
||||||
|
int32 _lastKeyDownAscii;
|
||||||
|
|
||||||
bool _mouseHidden;
|
bool _mouseHidden;
|
||||||
ZonePtr _hoverZone;
|
ZonePtr _hoverZone;
|
||||||
|
@ -73,7 +74,8 @@ class Input {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
kInputModeGame = 0,
|
kInputModeGame = 0,
|
||||||
kInputModeComment = 1
|
kInputModeComment = 1,
|
||||||
|
kInputModeDialogue = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,14 +101,13 @@ public:
|
||||||
|
|
||||||
uint16 readInput();
|
uint16 readInput();
|
||||||
InputData* updateInput();
|
InputData* updateInput();
|
||||||
|
void trackMouse(ZonePtr z);
|
||||||
void waitUntilLeftClick();
|
void waitUntilLeftClick();
|
||||||
void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
|
void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
|
||||||
uint32 getLastButtonEvent() { return _mouseButtons; }
|
uint32 getLastButtonEvent() { return _mouseButtons; }
|
||||||
|
bool getLastKeyDown(uint16 &ascii);
|
||||||
|
|
||||||
void stopHovering() {
|
void stopHovering();
|
||||||
_hoverZone = nullZonePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Parallaction
|
} // namespace Parallaction
|
||||||
|
|
|
@ -164,6 +164,11 @@ void Parallaction::updateView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Parallaction::hideDialogueStuff() {
|
||||||
|
_gfx->freeItems();
|
||||||
|
_balloonMan->freeBalloons();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Parallaction::freeCharacter() {
|
void Parallaction::freeCharacter() {
|
||||||
debugC(1, kDebugExec, "freeCharacter()");
|
debugC(1, kDebugExec, "freeCharacter()");
|
||||||
|
@ -297,16 +302,6 @@ void Parallaction::showLocationComment(const char *text, bool end) {
|
||||||
void Parallaction::processInput(InputData *data) {
|
void Parallaction::processInput(InputData *data) {
|
||||||
|
|
||||||
switch (data->_event) {
|
switch (data->_event) {
|
||||||
case kEvEnterZone:
|
|
||||||
debugC(2, kDebugInput, "processInput: kEvEnterZone");
|
|
||||||
_gfx->showFloatingLabel(data->_label);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kEvExitZone:
|
|
||||||
debugC(2, kDebugInput, "processInput: kEvExitZone");
|
|
||||||
_gfx->hideFloatingLabel();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kEvAction:
|
case kEvAction:
|
||||||
debugC(2, kDebugInput, "processInput: kEvAction");
|
debugC(2, kDebugInput, "processInput: kEvAction");
|
||||||
_input->stopHovering();
|
_input->stopHovering();
|
||||||
|
@ -317,7 +312,6 @@ void Parallaction::processInput(InputData *data) {
|
||||||
|
|
||||||
case kEvOpenInventory:
|
case kEvOpenInventory:
|
||||||
_input->stopHovering();
|
_input->stopHovering();
|
||||||
_gfx->hideFloatingLabel();
|
|
||||||
if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) {
|
if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) {
|
||||||
setArrowCursor();
|
setArrowCursor();
|
||||||
}
|
}
|
||||||
|
@ -367,25 +361,29 @@ void Parallaction::processInput(InputData *data) {
|
||||||
void Parallaction::runGame() {
|
void Parallaction::runGame() {
|
||||||
|
|
||||||
InputData *data = _input->updateInput();
|
InputData *data = _input->updateInput();
|
||||||
if (data->_event != kEvNone) {
|
if (_vm->quit())
|
||||||
processInput(data);
|
return;
|
||||||
|
|
||||||
|
if (_input->_inputMode == Input::kInputModeDialogue) {
|
||||||
|
runDialogueFrame();
|
||||||
|
} else {
|
||||||
|
if (data->_event != kEvNone) {
|
||||||
|
processInput(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vm->quit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
runPendingZones();
|
||||||
|
|
||||||
|
if (_vm->quit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_engineFlags & kEngineChangeLocation) {
|
||||||
|
changeLocation(_location._name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->quit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
runPendingZones();
|
|
||||||
|
|
||||||
if (_vm->quit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_engineFlags & kEngineChangeLocation) {
|
|
||||||
changeLocation(_location._name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_vm->quit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
_gfx->beginFrame();
|
_gfx->beginFrame();
|
||||||
|
|
||||||
if (_input->_inputMode == Input::kInputModeGame) {
|
if (_input->_inputMode == Input::kInputModeGame) {
|
||||||
|
@ -400,7 +398,6 @@ void Parallaction::runGame() {
|
||||||
|
|
||||||
// change this to endFrame?
|
// change this to endFrame?
|
||||||
updateView();
|
updateView();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -668,6 +665,7 @@ void Parallaction::beep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parallaction::scheduleLocationSwitch(const char *location) {
|
void Parallaction::scheduleLocationSwitch(const char *location) {
|
||||||
|
debugC(9, kDebugExec, "scheduleLocationSwitch(%s)\n", location);
|
||||||
strcpy(_location._name, location);
|
strcpy(_location._name, location);
|
||||||
_engineFlags |= kEngineChangeLocation;
|
_engineFlags |= kEngineChangeLocation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,8 +113,6 @@ enum EngineFlags {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kEvNone = 0,
|
kEvNone = 0,
|
||||||
kEvEnterZone = 1,
|
|
||||||
kEvExitZone = 2,
|
|
||||||
kEvAction = 3,
|
kEvAction = 3,
|
||||||
kEvOpenInventory = 4,
|
kEvOpenInventory = 4,
|
||||||
kEvCloseInventory = 5,
|
kEvCloseInventory = 5,
|
||||||
|
@ -164,6 +162,7 @@ class Debugger;
|
||||||
class Gfx;
|
class Gfx;
|
||||||
class SoundMan;
|
class SoundMan;
|
||||||
class Input;
|
class Input;
|
||||||
|
class DialogueManager;
|
||||||
|
|
||||||
struct Location {
|
struct Location {
|
||||||
|
|
||||||
|
@ -281,8 +280,6 @@ public:
|
||||||
uint16 runZone(ZonePtr z);
|
uint16 runZone(ZonePtr z);
|
||||||
void freeZones();
|
void freeZones();
|
||||||
|
|
||||||
void runDialogue(SpeakData*);
|
|
||||||
|
|
||||||
AnimationPtr findAnimation(const char *name);
|
AnimationPtr findAnimation(const char *name);
|
||||||
void freeAnimations();
|
void freeAnimations();
|
||||||
|
|
||||||
|
@ -425,10 +422,11 @@ public:
|
||||||
|
|
||||||
void setupBalloonManager();
|
void setupBalloonManager();
|
||||||
|
|
||||||
void hideDialogueStuff() {
|
void hideDialogueStuff();
|
||||||
_gfx->freeItems();
|
DialogueManager *_dialogueMan;
|
||||||
_balloonMan->freeBalloons();
|
void enterDialogueMode(ZonePtr z);
|
||||||
}
|
void exitDialogueMode();
|
||||||
|
void runDialogueFrame();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -212,13 +212,21 @@ void Parallaction_br::runPendingZones() {
|
||||||
if (_activeZone) {
|
if (_activeZone) {
|
||||||
z = _activeZone; // speak Zone or sound
|
z = _activeZone; // speak Zone or sound
|
||||||
_activeZone = nullZonePtr;
|
_activeZone = nullZonePtr;
|
||||||
runZone(z); // FIXME: BRA doesn't handle sound yet
|
if ((z->_type & 0xFFFF) == kZoneSpeak) {
|
||||||
|
enterDialogueMode(z);
|
||||||
|
} else {
|
||||||
|
runZone(z); // FIXME: BRA doesn't handle sound yet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_activeZone2) {
|
if (_activeZone2) {
|
||||||
z = _activeZone2; // speak Zone or sound
|
z = _activeZone2; // speak Zone or sound
|
||||||
_activeZone2 = nullZonePtr;
|
_activeZone2 = nullZonePtr;
|
||||||
runZone(z);
|
if ((z->_type & 0xFFFF) == kZoneSpeak) {
|
||||||
|
enterDialogueMode(z);
|
||||||
|
} else {
|
||||||
|
runZone(z); // FIXME: BRA doesn't handle sound yet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ void Parallaction_ns::setArrowCursor() {
|
||||||
debugC(1, kDebugInput, "setting mouse cursor to arrow");
|
debugC(1, kDebugInput, "setting mouse cursor to arrow");
|
||||||
|
|
||||||
// this stuff is needed to avoid artifacts with labels and selected items when switching cursors
|
// this stuff is needed to avoid artifacts with labels and selected items when switching cursors
|
||||||
_gfx->hideFloatingLabel();
|
_input->stopHovering();
|
||||||
_input->_activeItem._id = 0;
|
_input->_activeItem._id = 0;
|
||||||
|
|
||||||
_system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0);
|
_system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0);
|
||||||
|
@ -302,12 +302,11 @@ void Parallaction_ns::changeLocation(char *location) {
|
||||||
|
|
||||||
_soundMan->playLocationMusic(location);
|
_soundMan->playLocationMusic(location);
|
||||||
|
|
||||||
_gfx->hideFloatingLabel();
|
_input->stopHovering();
|
||||||
_gfx->freeLabels();
|
_gfx->freeLabels();
|
||||||
|
|
||||||
_zoneTrap = nullZonePtr;
|
_zoneTrap = nullZonePtr;
|
||||||
|
|
||||||
_input->stopHovering();
|
|
||||||
if (_engineFlags & kEngineBlockInput) {
|
if (_engineFlags & kEngineBlockInput) {
|
||||||
setArrowCursor();
|
setArrowCursor();
|
||||||
}
|
}
|
||||||
|
@ -420,6 +419,7 @@ void Parallaction_ns::changeCharacter(const char *name) {
|
||||||
Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
|
Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
|
||||||
_char._ani->gfxobj = _gfx->loadAnim(_char.getFullName());
|
_char._ani->gfxobj = _gfx->loadAnim(_char.getFullName());
|
||||||
_char._ani->gfxobj->setFlags(kGfxObjCharacter);
|
_char._ani->gfxobj->setFlags(kGfxObjCharacter);
|
||||||
|
_char._ani->gfxobj->clearFlags(kGfxObjNormal);
|
||||||
|
|
||||||
if (!_char.dummy()) {
|
if (!_char.dummy()) {
|
||||||
if (getPlatform() == Common::kPlatformAmiga) {
|
if (getPlatform() == Common::kPlatformAmiga) {
|
||||||
|
|
|
@ -354,6 +354,7 @@ void Parallaction_ns::walk(Character &character) {
|
||||||
if (newPos == curPos) {
|
if (newPos == curPos) {
|
||||||
debugC(1, kDebugWalk, "walk was blocked by an unforeseen obstacle");
|
debugC(1, kDebugWalk, "walk was blocked by an unforeseen obstacle");
|
||||||
finalizeWalk(character);
|
finalizeWalk(character);
|
||||||
|
targetPos = newPos; // when walking is interrupted, targetPos must be hacked so that a still frame can be selected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1175,15 +1175,8 @@ BamScene::BamScene(QueenEngine *vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
void BamScene::playSfx() {
|
void BamScene::playSfx() {
|
||||||
// Don't try to play all the sounds. This is only necessary for the
|
_vm->sound()->playSfx(_vm->logic()->currentRoomSfx());
|
||||||
// fight bam, in which the number of 'sfx bam frames' is too much
|
_lastSoundIndex = _index;
|
||||||
// important / too much closer. The original game does not have
|
|
||||||
// this problem since its playSfx() function returns immediately
|
|
||||||
// if a sound is already being played.
|
|
||||||
if (_lastSoundIndex == 0 || _index - _lastSoundIndex >= SFX_SKIP) {
|
|
||||||
_vm->sound()->playSfx(_vm->logic()->currentRoomSfx());
|
|
||||||
_lastSoundIndex = _index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BamScene::prepareAnimation() {
|
void BamScene::prepareAnimation() {
|
||||||
|
|
|
@ -248,10 +248,6 @@ public:
|
||||||
F_REQ_STOP = 2
|
F_REQ_STOP = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
SFX_SKIP = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16 _flag, _index;
|
uint16 _flag, _index;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -227,11 +227,6 @@ void PCSound::setVolume(int vol) {
|
||||||
_music->setVolume(vol);
|
_music->setVolume(vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCSound::waitFinished(bool isSpeech) {
|
|
||||||
while (_mixer->isSoundHandleActive(isSpeech ? _speechHandle : _sfxHandle))
|
|
||||||
_vm->input()->delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCSound::playSound(const char *base, bool isSpeech) {
|
void PCSound::playSound(const char *base, bool isSpeech) {
|
||||||
char name[13];
|
char name[13];
|
||||||
strcpy(name, base);
|
strcpy(name, base);
|
||||||
|
@ -241,7 +236,13 @@ void PCSound::playSound(const char *base, bool isSpeech) {
|
||||||
name[i] = '0';
|
name[i] = '0';
|
||||||
}
|
}
|
||||||
strcat(name, ".SB");
|
strcat(name, ".SB");
|
||||||
waitFinished(isSpeech);
|
if (isSpeech) {
|
||||||
|
while (_mixer->isSoundHandleActive(_speechHandle)) {
|
||||||
|
_vm->input()->delay(10);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_mixer->stopHandle(_sfxHandle);
|
||||||
|
}
|
||||||
uint32 size;
|
uint32 size;
|
||||||
Common::File *f = _vm->resource()->findSound(name, &size);
|
Common::File *f = _vm->resource()->findSound(name, &size);
|
||||||
if (f) {
|
if (f) {
|
||||||
|
@ -253,6 +254,8 @@ void PCSound::playSound(const char *base, bool isSpeech) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBSound::playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *soundHandle) {
|
void SBSound::playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *soundHandle) {
|
||||||
|
// In order to simplify the code, we don't parse the .sb header but hard-code the
|
||||||
|
// values. Refer to tracker item #1876741 for details on the format/fields.
|
||||||
int headerSize;
|
int headerSize;
|
||||||
f->seek(2, SEEK_CUR);
|
f->seek(2, SEEK_CUR);
|
||||||
uint16 version = f->readUint16LE();
|
uint16 version = f->readUint16LE();
|
||||||
|
|
|
@ -143,7 +143,6 @@ public:
|
||||||
void setVolume(int vol);
|
void setVolume(int vol);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void waitFinished(bool isSpeech);
|
|
||||||
void playSound(const char *base, bool isSpeech);
|
void playSound(const char *base, bool isSpeech);
|
||||||
|
|
||||||
virtual void playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *soundHandle) = 0;
|
virtual void playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *soundHandle) = 0;
|
||||||
|
|
|
@ -949,7 +949,7 @@ SaveStateList ScummMetaEngine::listSaves(const char *target) const {
|
||||||
sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
|
sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
|
||||||
|
|
||||||
SaveStateList saveList;
|
SaveStateList saveList;
|
||||||
for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
|
for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
|
||||||
// Obtain the last 2 digits of the filename, since they correspond to the save slot
|
// Obtain the last 2 digits of the filename, since they correspond to the save slot
|
||||||
int slotNum = atoi(file->c_str() + file->size() - 2);
|
int slotNum = atoi(file->c_str() + file->size() - 2);
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||||
break;
|
break;
|
||||||
case GUI::kListSelectionChangedCmd: {
|
case GUI::kListSelectionChangedCmd: {
|
||||||
if (_gfxWidget) {
|
if (_gfxWidget) {
|
||||||
updateInfos();
|
updateInfos(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_saveMode) {
|
if (_saveMode) {
|
||||||
|
@ -350,7 +350,7 @@ void SaveLoadChooser::reflowLayout() {
|
||||||
_fillR = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR");
|
_fillR = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR");
|
||||||
_fillG = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG");
|
_fillG = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG");
|
||||||
_fillB = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB");
|
_fillB = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB");
|
||||||
updateInfos();
|
updateInfos(false);
|
||||||
} else {
|
} else {
|
||||||
_container->setFlags(GUI::WIDGET_INVISIBLE);
|
_container->setFlags(GUI::WIDGET_INVISIBLE);
|
||||||
_gfxWidget->setFlags(GUI::WIDGET_INVISIBLE);
|
_gfxWidget->setFlags(GUI::WIDGET_INVISIBLE);
|
||||||
|
@ -362,7 +362,7 @@ void SaveLoadChooser::reflowLayout() {
|
||||||
Dialog::reflowLayout();
|
Dialog::reflowLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveLoadChooser::updateInfos() {
|
void SaveLoadChooser::updateInfos(bool redraw) {
|
||||||
int selItem = _list->getSelected();
|
int selItem = _list->getSelected();
|
||||||
Graphics::Surface *thumb;
|
Graphics::Surface *thumb;
|
||||||
thumb = _vm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
|
thumb = _vm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
|
||||||
|
@ -376,7 +376,8 @@ void SaveLoadChooser::updateInfos() {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete thumb;
|
delete thumb;
|
||||||
_gfxWidget->draw();
|
if (redraw)
|
||||||
|
_gfxWidget->draw();
|
||||||
|
|
||||||
InfoStuff infos;
|
InfoStuff infos;
|
||||||
memset(&infos, 0, sizeof(InfoStuff));
|
memset(&infos, 0, sizeof(InfoStuff));
|
||||||
|
@ -386,12 +387,14 @@ void SaveLoadChooser::updateInfos() {
|
||||||
(infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
|
(infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
|
||||||
infos.date & 0xFFFF);
|
infos.date & 0xFFFF);
|
||||||
_date->setLabel(buffer);
|
_date->setLabel(buffer);
|
||||||
_date->draw();
|
if (redraw)
|
||||||
|
_date->draw();
|
||||||
|
|
||||||
snprintf(buffer, 32, "Time: %.2d:%.2d",
|
snprintf(buffer, 32, "Time: %.2d:%.2d",
|
||||||
(infos.time >> 8) & 0xFF, infos.time & 0xFF);
|
(infos.time >> 8) & 0xFF, infos.time & 0xFF);
|
||||||
_time->setLabel(buffer);
|
_time->setLabel(buffer);
|
||||||
_time->draw();
|
if (redraw)
|
||||||
|
_time->draw();
|
||||||
|
|
||||||
int minutes = infos.playtime / 60;
|
int minutes = infos.playtime / 60;
|
||||||
int hours = minutes / 60;
|
int hours = minutes / 60;
|
||||||
|
@ -400,19 +403,23 @@ void SaveLoadChooser::updateInfos() {
|
||||||
snprintf(buffer, 32, "Playtime: %.2d:%.2d",
|
snprintf(buffer, 32, "Playtime: %.2d:%.2d",
|
||||||
hours & 0xFF, minutes & 0xFF);
|
hours & 0xFF, minutes & 0xFF);
|
||||||
_playtime->setLabel(buffer);
|
_playtime->setLabel(buffer);
|
||||||
_playtime->draw();
|
if (redraw)
|
||||||
|
_playtime->draw();
|
||||||
} else {
|
} else {
|
||||||
snprintf(buffer, 32, "No date saved");
|
snprintf(buffer, 32, "No date saved");
|
||||||
_date->setLabel(buffer);
|
_date->setLabel(buffer);
|
||||||
_date->draw();
|
if (redraw)
|
||||||
|
_date->draw();
|
||||||
|
|
||||||
snprintf(buffer, 32, "No time saved");
|
snprintf(buffer, 32, "No time saved");
|
||||||
_time->setLabel(buffer);
|
_time->setLabel(buffer);
|
||||||
_time->draw();
|
if (redraw)
|
||||||
|
_time->draw();
|
||||||
|
|
||||||
snprintf(buffer, 32, "No playtime saved");
|
snprintf(buffer, 32, "No playtime saved");
|
||||||
_playtime->setLabel(buffer);
|
_playtime->setLabel(buffer);
|
||||||
_playtime->draw();
|
if (redraw)
|
||||||
|
_playtime->draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ protected:
|
||||||
|
|
||||||
uint8 _fillR, _fillG, _fillB;
|
uint8 _fillR, _fillG, _fillB;
|
||||||
|
|
||||||
void updateInfos();
|
void updateInfos(bool redraw);
|
||||||
public:
|
public:
|
||||||
SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine);
|
SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine);
|
||||||
~SaveLoadChooser();
|
~SaveLoadChooser();
|
||||||
|
|
|
@ -102,10 +102,10 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, SoundDesc *sound,
|
||||||
int32 version = file->readUint32BE();
|
int32 version = file->readUint32BE();
|
||||||
if (version != 3) {
|
if (version != 3) {
|
||||||
if (version == 2) {
|
if (version == 2) {
|
||||||
warning("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version of compressed *.bun file, expected 3, but it's 2.");
|
warning("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version of compressed *.bun file, expected 3, but it's 2");
|
||||||
warning("Suggested to recompress with latest tool from daily builds.");
|
warning("Suggested to recompress with latest tool from daily builds");
|
||||||
} else
|
} else
|
||||||
error("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version number, expected 3, but it's: %d.", version);
|
error("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version number, expected 3, but it's: %d", version);
|
||||||
}
|
}
|
||||||
sound->bits = file->readUint32BE();
|
sound->bits = file->readUint32BE();
|
||||||
sound->freq = file->readUint32BE();
|
sound->freq = file->readUint32BE();
|
||||||
|
|
|
@ -52,9 +52,11 @@ namespace Sword2 {
|
||||||
static Audio::AudioStream *makeCLUStream(Common::File *fp, int size);
|
static Audio::AudioStream *makeCLUStream(Common::File *fp, int size);
|
||||||
|
|
||||||
static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base, int cd, uint32 id, uint32 *numSamples) {
|
static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base, int cd, uint32 id, uint32 *numSamples) {
|
||||||
debug(3, "Playing %s from CD %d", base, cd);
|
bool alreadyOpen;
|
||||||
|
|
||||||
if (!fh->file.isOpen()) {
|
if (!fh->file.isOpen()) {
|
||||||
|
alreadyOpen = false;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *ext;
|
const char *ext;
|
||||||
int mode;
|
int mode;
|
||||||
|
@ -75,16 +77,14 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
|
||||||
char filename[20];
|
char filename[20];
|
||||||
|
|
||||||
for (int i = 0; i < ARRAYSIZE(file_types); i++) {
|
for (int i = 0; i < ARRAYSIZE(file_types); i++) {
|
||||||
Common::File f;
|
|
||||||
|
|
||||||
sprintf(filename, "%s%d.%s", base, cd, file_types[i].ext);
|
sprintf(filename, "%s%d.%s", base, cd, file_types[i].ext);
|
||||||
if (f.open(filename)) {
|
if (Common::File::exists(filename)) {
|
||||||
soundMode = file_types[i].mode;
|
soundMode = file_types[i].mode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s.%s", base, file_types[i].ext);
|
sprintf(filename, "%s.%s", base, file_types[i].ext);
|
||||||
if (f.open(filename)) {
|
if (Common::File::exists(filename)) {
|
||||||
soundMode = file_types[i].mode;
|
soundMode = file_types[i].mode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,8 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
|
||||||
fh->idxTab = NULL;
|
fh->idxTab = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
alreadyOpen = true;
|
||||||
|
|
||||||
uint32 entrySize = (fh->fileType == kCLUMode) ? 2 : 3;
|
uint32 entrySize = (fh->fileType == kCLUMode) ? 2 : 3;
|
||||||
|
|
||||||
|
@ -134,7 +135,13 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
|
||||||
*numSamples = len;
|
*numSamples = len;
|
||||||
|
|
||||||
if (!pos || !len) {
|
if (!pos || !len) {
|
||||||
fh->file.close();
|
// We couldn't find the sound. Possibly as a result of a bad
|
||||||
|
// installation (e.g. using the music file from CD 2 as the
|
||||||
|
// first music file). Don't close the file if it was already
|
||||||
|
// open though, because something is playing from it.
|
||||||
|
warning("getAudioStream: Could not find %s ID %d! Possibly the wrong file", base, id);
|
||||||
|
if (!alreadyOpen)
|
||||||
|
fh->file.close();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ private:
|
||||||
void refill();
|
void refill();
|
||||||
|
|
||||||
inline bool eosIntern() const {
|
inline bool eosIntern() const {
|
||||||
return _pos >= _bufferEnd;
|
return !_file->isOpen() || _pos >= _bufferEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -5,16 +5,25 @@
|
||||||
class StringTestSuite : public CxxTest::TestSuite
|
class StringTestSuite : public CxxTest::TestSuite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void test_empty_clear( void )
|
void test_constructors(void) {
|
||||||
{
|
Common::String str("test-string");
|
||||||
|
TS_ASSERT( str == "test-string" );
|
||||||
|
str = Common::String(str.c_str()+5, 3);
|
||||||
|
TS_ASSERT( str == "str" );
|
||||||
|
str = "test-string";
|
||||||
|
TS_ASSERT( str == "test-string" );
|
||||||
|
str = Common::String(str.c_str()+5, str.c_str()+8);
|
||||||
|
TS_ASSERT( str == "str" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_empty_clear(void) {
|
||||||
Common::String str("test");
|
Common::String str("test");
|
||||||
TS_ASSERT( !str.empty() );
|
TS_ASSERT( !str.empty() );
|
||||||
str.clear();
|
str.clear();
|
||||||
TS_ASSERT( str.empty() );
|
TS_ASSERT( str.empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lastChar( void )
|
void test_lastChar(void) {
|
||||||
{
|
|
||||||
Common::String str;
|
Common::String str;
|
||||||
TS_ASSERT_EQUALS( str.lastChar(), '\0' );
|
TS_ASSERT_EQUALS( str.lastChar(), '\0' );
|
||||||
str = "test";
|
str = "test";
|
||||||
|
@ -23,8 +32,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( str2.lastChar(), 'r' );
|
TS_ASSERT_EQUALS( str2.lastChar(), 'r' );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_concat1( void )
|
void test_concat1(void) {
|
||||||
{
|
|
||||||
Common::String str("foo");
|
Common::String str("foo");
|
||||||
Common::String str2("bar");
|
Common::String str2("bar");
|
||||||
str += str2;
|
str += str2;
|
||||||
|
@ -32,22 +40,19 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( str2, "bar" );
|
TS_ASSERT_EQUALS( str2, "bar" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_concat2( void )
|
void test_concat2(void) {
|
||||||
{
|
|
||||||
Common::String str("foo");
|
Common::String str("foo");
|
||||||
str += "bar";
|
str += "bar";
|
||||||
TS_ASSERT_EQUALS( str, "foobar" );
|
TS_ASSERT_EQUALS( str, "foobar" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_concat3( void )
|
void test_concat3(void) {
|
||||||
{
|
|
||||||
Common::String str("foo");
|
Common::String str("foo");
|
||||||
str += 'X';
|
str += 'X';
|
||||||
TS_ASSERT_EQUALS( str, "fooX" );
|
TS_ASSERT_EQUALS( str, "fooX" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refCount( void )
|
void test_refCount(void) {
|
||||||
{
|
|
||||||
Common::String foo1("foo");
|
Common::String foo1("foo");
|
||||||
Common::String foo2("foo");
|
Common::String foo2("foo");
|
||||||
Common::String foo3(foo2);
|
Common::String foo3(foo2);
|
||||||
|
@ -57,8 +62,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( foo3, "foo""X" );
|
TS_ASSERT_EQUALS( foo3, "foo""X" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refCount2( void )
|
void test_refCount2(void) {
|
||||||
{
|
|
||||||
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||||
Common::String foo2("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
Common::String foo2("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||||
Common::String foo3(foo2);
|
Common::String foo3(foo2);
|
||||||
|
@ -68,8 +72,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""X" );
|
TS_ASSERT_EQUALS( foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""X" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refCount3( void )
|
void test_refCount3(void) {
|
||||||
{
|
|
||||||
Common::String foo1("0123456789abcdefghijk");
|
Common::String foo1("0123456789abcdefghijk");
|
||||||
Common::String foo2("0123456789abcdefghijk");
|
Common::String foo2("0123456789abcdefghijk");
|
||||||
Common::String foo3(foo2);
|
Common::String foo3(foo2);
|
||||||
|
@ -79,8 +82,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( foo3, "0123456789abcdefghijk""0123456789abcdefghijk" );
|
TS_ASSERT_EQUALS( foo3, "0123456789abcdefghijk""0123456789abcdefghijk" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refCount4( void )
|
void test_refCount4(void) {
|
||||||
{
|
|
||||||
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||||
Common::String foo2("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
Common::String foo2("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||||
Common::String foo3(foo2);
|
Common::String foo3(foo2);
|
||||||
|
@ -90,8 +92,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd" );
|
TS_ASSERT_EQUALS( foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_hasPrefix( void )
|
void test_hasPrefix(void) {
|
||||||
{
|
|
||||||
Common::String str("this/is/a/test, haha");
|
Common::String str("this/is/a/test, haha");
|
||||||
TS_ASSERT_EQUALS( str.hasPrefix(""), true );
|
TS_ASSERT_EQUALS( str.hasPrefix(""), true );
|
||||||
TS_ASSERT_EQUALS( str.hasPrefix("this"), true );
|
TS_ASSERT_EQUALS( str.hasPrefix("this"), true );
|
||||||
|
@ -99,8 +100,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( str.hasPrefix("foo"), false );
|
TS_ASSERT_EQUALS( str.hasPrefix("foo"), false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_hasSuffix( void )
|
void test_hasSuffix(void) {
|
||||||
{
|
|
||||||
Common::String str("this/is/a/test, haha");
|
Common::String str("this/is/a/test, haha");
|
||||||
TS_ASSERT_EQUALS( str.hasSuffix(""), true );
|
TS_ASSERT_EQUALS( str.hasSuffix(""), true );
|
||||||
TS_ASSERT_EQUALS( str.hasSuffix("haha"), true );
|
TS_ASSERT_EQUALS( str.hasSuffix("haha"), true );
|
||||||
|
@ -108,8 +108,7 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( str.hasSuffix("hahah"), false );
|
TS_ASSERT_EQUALS( str.hasSuffix("hahah"), false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_contains( void )
|
void test_contains(void) {
|
||||||
{
|
|
||||||
Common::String str("this/is/a/test, haha");
|
Common::String str("this/is/a/test, haha");
|
||||||
TS_ASSERT_EQUALS( str.contains(""), true );
|
TS_ASSERT_EQUALS( str.contains(""), true );
|
||||||
TS_ASSERT_EQUALS( str.contains("haha"), true );
|
TS_ASSERT_EQUALS( str.contains("haha"), true );
|
||||||
|
@ -117,15 +116,13 @@ class StringTestSuite : public CxxTest::TestSuite
|
||||||
TS_ASSERT_EQUALS( str.contains("test"), true );
|
TS_ASSERT_EQUALS( str.contains("test"), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_toLowercase( void )
|
void test_toLowercase(void) {
|
||||||
{
|
|
||||||
Common::String str("Test it, NOW! 42");
|
Common::String str("Test it, NOW! 42");
|
||||||
str.toLowercase();
|
str.toLowercase();
|
||||||
TS_ASSERT_EQUALS( str, "test it, now! 42" );
|
TS_ASSERT_EQUALS( str, "test it, now! 42" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_toUppercase( void )
|
void test_toUppercase(void) {
|
||||||
{
|
|
||||||
Common::String str("Test it, NOW! 42");
|
Common::String str("Test it, NOW! 42");
|
||||||
str.toUppercase();
|
str.toUppercase();
|
||||||
TS_ASSERT_EQUALS( str, "TEST IT, NOW! 42" );
|
TS_ASSERT_EQUALS( str, "TEST IT, NOW! 42" );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue