Add Nintendo 64 port to trunk.
svn-id: r46773
This commit is contained in:
parent
0de5bac349
commit
a108df30a7
22 changed files with 2159 additions and 3 deletions
47
backends/fs/n64/n64-fs-factory.cpp
Normal file
47
backends/fs/n64/n64-fs-factory.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef __N64__
|
||||
|
||||
#include <n64utils.h>
|
||||
|
||||
#include "backends/fs/n64/n64-fs-factory.h"
|
||||
#include "backends/fs/n64/n64-fs.cpp"
|
||||
|
||||
AbstractFSNode *N64FilesystemFactory::makeRootFileNode() const {
|
||||
return new N64FilesystemNode();
|
||||
}
|
||||
|
||||
AbstractFSNode *N64FilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||
char buf[MAXPATHLEN];
|
||||
return romfs_getcwd(buf, MAXPATHLEN) ? new N64FilesystemNode(Common::String(buf), false) : NULL;
|
||||
}
|
||||
|
||||
AbstractFSNode *N64FilesystemFactory::makeFileNodePath(const Common::String &path) const {
|
||||
assert(!path.empty());
|
||||
return new N64FilesystemNode(path, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
42
backends/fs/n64/n64-fs-factory.h
Normal file
42
backends/fs/n64/n64-fs-factory.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef N64_FILESYSTEM_FACTORY_H
|
||||
#define N64_FILESYSTEM_FACTORY_H
|
||||
|
||||
#include <romfs.h>
|
||||
#include "backends/fs/fs-factory.h"
|
||||
|
||||
/**
|
||||
* Creates N64FilesystemNode objects.
|
||||
*
|
||||
* Parts of this class are documented in the base interface class, FilesystemFactory.
|
||||
*/
|
||||
class N64FilesystemFactory : public FilesystemFactory {
|
||||
virtual AbstractFSNode *makeRootFileNode() const;
|
||||
virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
|
||||
virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
|
||||
};
|
||||
|
||||
#endif /*N64_FILESYSTEM_FACTORY_H*/
|
213
backends/fs/n64/n64-fs.cpp
Normal file
213
backends/fs/n64/n64-fs.cpp
Normal file
|
@ -0,0 +1,213 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __N64__
|
||||
|
||||
#include "backends/fs/abstract-fs.h"
|
||||
#include "backends/fs/stdiostream.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <n64utils.h>
|
||||
|
||||
#define ROOT_PATH "/"
|
||||
|
||||
/**
|
||||
* Implementation of the ScummVM file system API based on N64 Hkz romfs.
|
||||
*
|
||||
* Parts of this class are documented in the base interface class, AbstractFSNode.
|
||||
*/
|
||||
class N64FilesystemNode : public AbstractFSNode {
|
||||
protected:
|
||||
Common::String _displayName;
|
||||
Common::String _path;
|
||||
bool _isDirectory;
|
||||
bool _isValid;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a N64FilesystemNode with the root node as path.
|
||||
*/
|
||||
N64FilesystemNode();
|
||||
|
||||
/**
|
||||
* Creates a N64FilesystemNode for a given path.
|
||||
*
|
||||
* @param path Common::String with the path the new node should point to.
|
||||
* @param verify true if the isValid and isDirectory flags should be verified during the construction.
|
||||
*/
|
||||
N64FilesystemNode(const Common::String &p, bool verify = true);
|
||||
|
||||
virtual bool exists() const;
|
||||
virtual Common::String getDisplayName() const {
|
||||
return _displayName;
|
||||
}
|
||||
virtual Common::String getName() const {
|
||||
return _displayName;
|
||||
}
|
||||
virtual Common::String getPath() const {
|
||||
return _path;
|
||||
}
|
||||
virtual bool isDirectory() const {
|
||||
return _isDirectory;
|
||||
}
|
||||
virtual bool isReadable() const;
|
||||
virtual bool isWritable() const;
|
||||
|
||||
virtual AbstractFSNode *getChild(const Common::String &n) const;
|
||||
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||
virtual AbstractFSNode *getParent() const;
|
||||
|
||||
virtual Common::SeekableReadStream *createReadStream();
|
||||
virtual Common::WriteStream *createWriteStream();
|
||||
};
|
||||
|
||||
N64FilesystemNode::N64FilesystemNode() {
|
||||
_isDirectory = true;
|
||||
_displayName = "Root";
|
||||
_isValid = true;
|
||||
_path = ROOT_PATH;
|
||||
}
|
||||
|
||||
N64FilesystemNode::N64FilesystemNode(const Common::String &p, bool verify) {
|
||||
assert(p.size() > 0);
|
||||
|
||||
_path = p;
|
||||
_displayName = lastPathComponent(_path, '/');
|
||||
_isValid = true;
|
||||
_isDirectory = true;
|
||||
|
||||
// Check if it's a dir
|
||||
ROMFILE *tmpfd = romfs_open(p.c_str(), "r");
|
||||
if (tmpfd) {
|
||||
_isDirectory = (tmpfd->type == 0 || tmpfd->type == 1);
|
||||
romfs_close(tmpfd);
|
||||
}
|
||||
}
|
||||
|
||||
bool N64FilesystemNode::exists() const {
|
||||
int ret = -1;
|
||||
|
||||
ret = romfs_access(_path.c_str(), F_OK);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
bool N64FilesystemNode::isReadable() const {
|
||||
int ret = -1;
|
||||
|
||||
ret = romfs_access(_path.c_str(), R_OK);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
// We can't write on ROMFS!
|
||||
bool N64FilesystemNode::isWritable() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AbstractFSNode *N64FilesystemNode::getChild(const Common::String &n) const {
|
||||
// FIXME: Pretty lame implementation! We do no error checking to speak
|
||||
// of, do not check if this is a special node, etc.
|
||||
assert(_isDirectory);
|
||||
|
||||
Common::String newPath(_path);
|
||||
if (_path.lastChar() != '/')
|
||||
newPath += '/';
|
||||
newPath += n;
|
||||
|
||||
return new N64FilesystemNode(newPath, true);
|
||||
}
|
||||
|
||||
bool N64FilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||
assert(_isDirectory);
|
||||
ROMDIR *dirp = romfs_opendir(_path.c_str());
|
||||
romfs_dirent *dp;
|
||||
|
||||
if (dirp == NULL)
|
||||
return false;
|
||||
|
||||
// loop over dir entries using readdir
|
||||
while ((dp = romfs_readdir(dirp)) != NULL) {
|
||||
// Skip 'invisible' files if necessary
|
||||
if (dp->entryname[0] == '.' && !hidden) {
|
||||
free(dp);
|
||||
continue;
|
||||
}
|
||||
// Skip '.' and '..' to avoid cycles
|
||||
if ((dp->entryname[0] == '.' && dp->entryname[1] == 0) || (dp->entryname[0] == '.' && dp->entryname[1] == '.')) {
|
||||
free(dp);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start with a clone of this node, with the correct path set
|
||||
N64FilesystemNode entry(*this);
|
||||
entry._displayName = dp->entryname;
|
||||
if (_path.lastChar() != '/')
|
||||
entry._path += '/';
|
||||
entry._path += entry._displayName;
|
||||
|
||||
// Force validity for now...
|
||||
entry._isValid = 1;
|
||||
|
||||
entry._isDirectory = (dp->type == 0 || dp->type == 1);
|
||||
|
||||
// Honor the chosen mode
|
||||
if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) ||
|
||||
(mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory)) {
|
||||
|
||||
free(dp);
|
||||
continue;
|
||||
}
|
||||
|
||||
myList.push_back(new N64FilesystemNode(entry));
|
||||
|
||||
free(dp);
|
||||
}
|
||||
romfs_closedir(dirp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AbstractFSNode *N64FilesystemNode::getParent() const {
|
||||
if (_path == ROOT_PATH)
|
||||
return 0;
|
||||
|
||||
const char *start = _path.c_str();
|
||||
const char *end = lastPathComponent(_path, '/');
|
||||
|
||||
return new N64FilesystemNode(Common::String(start, end - start), false);
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *N64FilesystemNode::createReadStream() {
|
||||
return StdioStream::makeFromPath(getPath(), false);
|
||||
}
|
||||
|
||||
Common::WriteStream *N64FilesystemNode::createWriteStream() {
|
||||
return StdioStream::makeFromPath(getPath(), true);
|
||||
}
|
||||
|
||||
#endif //#ifdef __N64__
|
||||
|
|
@ -25,6 +25,28 @@
|
|||
|
||||
#include "backends/fs/stdiostream.h"
|
||||
|
||||
#ifdef __N64__
|
||||
#include <romfs.h>
|
||||
|
||||
#undef feof
|
||||
#undef clearerr
|
||||
#undef ferror
|
||||
|
||||
#undef FILE
|
||||
#define FILE ROMFILE
|
||||
|
||||
#define fopen(name, mode) romfs_open(name, mode)
|
||||
#define fclose(handle) romfs_close(handle)
|
||||
#define fread(ptr, size, items, file) romfs_read(ptr, size, items, file)
|
||||
#define fwrite(ptr, size, items, file) romfs_write(ptr, size, items, file)
|
||||
#define feof(handle) romfs_eof(handle)
|
||||
#define ftell(handle) romfs_tell(handle)
|
||||
#define fseek(handle, offset, whence) romfs_seek(handle, offset, whence)
|
||||
#define clearerr(handle) romfs_clearerr(handle)
|
||||
#define fflush(file) romfs_flush(file)
|
||||
#define ferror(handle) romfs_error(handle)
|
||||
#endif
|
||||
|
||||
StdioStream::StdioStream(void *handle) : _handle(handle) {
|
||||
assert(handle);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ MODULE_OBJS := \
|
|||
fs/symbian/symbian-fs-factory.o \
|
||||
fs/windows/windows-fs-factory.o \
|
||||
fs/wii/wii-fs-factory.o \
|
||||
fs/n64/n64-fs-factory.o \
|
||||
keymapper/action.o \
|
||||
keymapper/keymap.o \
|
||||
keymapper/keymapper.o \
|
||||
|
|
93
backends/platform/n64/Makefile
Normal file
93
backends/platform/n64/Makefile
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
TOOLPATH = /opt/mips64-toolchain
|
||||
LIBN64PATH = $(TOOLPATH)/hkz-libn64/
|
||||
GCCN64PREFIX = $(TOOLPATH)/bin/mips64-
|
||||
|
||||
srcdir = ../../..
|
||||
VPATH = $(srcdir)
|
||||
|
||||
CC = $(GCCN64PREFIX)gcc
|
||||
CXX = $(GCCN64PREFIX)g++
|
||||
AS = $(GCCN64PREFIX)as
|
||||
LD = $(GCCN64PREFIX)g++
|
||||
OBJCOPY = $(GCCN64PREFIX)objcopy
|
||||
AR = $(GCCN64PREFIX)ar cru
|
||||
RANLIB = $(GCCN64PREFIX)ranlib
|
||||
|
||||
DEFINES += -D__N64__ -DLIMIT_FPS -DNONSTANDARD_PORT -DDISABLE_DEFAULT_SAVEFILEMANAGER -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_FANCY_THEMES -DDISABLE_DOSBOX_OPL -DENABLE_VKEYBD -DUSE_ZLIB
|
||||
LIBS += -lpakfs -ln64 -ln64utils -lromfs
|
||||
|
||||
DEFINES += -D_ENABLE_DEBUG_
|
||||
|
||||
USE_LIBMAD=0
|
||||
USE_LIBOGG=1
|
||||
|
||||
ifeq ($(USE_LIBMAD),1)
|
||||
DEFINES += -DUSE_MAD
|
||||
LIBS += -lmad
|
||||
endif
|
||||
ifeq ($(USE_LIBOGG), 1)
|
||||
DEFINES += -DUSE_VORBIS -DUSE_TREMOR
|
||||
LIBS += -lvorbisidec
|
||||
endif
|
||||
|
||||
LIBS += -lm -lstdc++ -lc -lgcc -lz -lnosys
|
||||
|
||||
CXXFLAGS = -g -O2 -fomit-frame-pointer -march=vr4300 -mtune=vr4300 -mno-extern-sdata -fno-rtti -fno-exceptions -Wno-multichar -Wshadow -I$(LIBN64PATH) -I$(TOOLPATH)/include -I./ -I$(srcdir) -I$(srcdir)/engines
|
||||
LDFLAGS = -g -march=vr4300 -mtune=vr4300 -nodefaultlibs -nostartfiles -mno-crt0 -L$(LIBN64PATH) -L$(TOOLPATH)/lib $(LIBS) -T n64ld_cpp.x -Xlinker -Map -Xlinker scummvm.map
|
||||
|
||||
TARGET = scummvm
|
||||
DEPDIR = .deps
|
||||
CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP
|
||||
MKDIR = mkdir -p
|
||||
RM = rm -f
|
||||
RM_REC = rm -rf
|
||||
|
||||
VERBOSE_BUILD=0
|
||||
HAVE_GCC3=1
|
||||
DISABLE_SCALERS=1
|
||||
DISABLE_HQ_SCALER=1
|
||||
USE_MT32EMU=0
|
||||
USE_RGB_COLOR=0
|
||||
|
||||
ENABLED=STATIC_PLUGIN
|
||||
|
||||
#ENABLE_SCUMM=$(ENABLED)
|
||||
#ENABLE_SKY=$(ENABLED)
|
||||
#ENABLE_SCI=$(ENABLED)
|
||||
#ENABLE_GOB=$(ENABLED)
|
||||
#ENABLE_PARALLACTION=$(ENABLED)
|
||||
#ENABLE_KYRA=$(ENABLED)
|
||||
#ENABLE_AGOS = $(ENABLED)
|
||||
#ENABLE_AGI = $(ENABLED)
|
||||
#ENABLE_QUEEN = $(ENABLED)
|
||||
#ENABLE_MADE = $(ENABLED)
|
||||
ENABLE_SAGA = $(ENABLED)
|
||||
|
||||
OBJS := nintendo64.o osys_n64_base.o osys_n64_events.o osys_n64_utilities.o pakfs_save_manager.o
|
||||
|
||||
include $(srcdir)/Makefile.common
|
||||
|
||||
MODULE_DIRS += ./
|
||||
|
||||
all: $(TARGET).v64
|
||||
|
||||
$(TARGET).v64: $(TARGET).bin ROMFS.img bootcode
|
||||
cat bootcode $(TARGET).bin ROMFS.img > $(TARGET).v64
|
||||
./pad_rom.sh
|
||||
|
||||
ROMFS.img:
|
||||
genromfs -f ./ROMFS.img -d ./ROMFS -V romtest
|
||||
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(LD) -o $(TARGET).elf $(OBJS) $(LDFLAGS)
|
||||
|
||||
$(TARGET).bin : $(TARGET).elf
|
||||
$(OBJCOPY) $(TARGET).elf $(TARGET).bin -O binary
|
||||
|
||||
spotless : distclean
|
||||
$(RM) *.bin *.elf *.v64 *.img *.bak *.tmp *.map
|
||||
|
||||
send: $(TARGET).v64
|
||||
sudo ucon64 --xv64 $(TARGET).v64
|
||||
|
10
backends/platform/n64/module.mk
Normal file
10
backends/platform/n64/module.mk
Normal file
|
@ -0,0 +1,10 @@
|
|||
MODULE := backends/platform/n64
|
||||
|
||||
MODULE_OBJS := \
|
||||
nintendo64.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
backends/platform/n64/
|
||||
|
||||
# We don't use the rules.mk here on purpose
|
||||
OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
|
35
backends/platform/n64/nintendo64.cpp
Normal file
35
backends/platform/n64/nintendo64.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "osys_n64.h"
|
||||
|
||||
int main(void) {
|
||||
g_system = new OSystem_N64();
|
||||
assert(g_system);
|
||||
|
||||
// Invoke the actual ScummVM main entry point:
|
||||
int res = scummvm_main(0, NULL);
|
||||
g_system->quit(); // TODO: Consider removing / replacing this!
|
||||
return res;
|
||||
}
|
||||
|
206
backends/platform/n64/osys_n64.h
Normal file
206
backends/platform/n64/osys_n64.h
Normal file
|
@ -0,0 +1,206 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OSYS_N64_H__
|
||||
#define __OSYS_N64_H__
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "common/config-manager.h"
|
||||
|
||||
#include "backends/base-backend.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
|
||||
#include "base/main.h"
|
||||
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/colormasks.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
#include "sound/mixer_intern.h"
|
||||
|
||||
#include <libn64.h>
|
||||
#include <n64utils.h>
|
||||
|
||||
#define DEFAULT_SOUND_SAMPLE_RATE 8000 // 8 kHz
|
||||
//#define DEFAULT_SOUND_SAMPLE_RATE 11025 // 11 kHz
|
||||
|
||||
// Limit the N64 resolution to 320x240, because framebuffer
|
||||
// at higher resolutions would be too slow and memory hogging
|
||||
#define DEFAULT_SCREEN_WIDTH 320
|
||||
#define DEFAULT_SCREEN_HEIGHT 240
|
||||
|
||||
#define N64_PAL_FPS 25
|
||||
#define N64_NTSC_FPS 30
|
||||
|
||||
typedef int (*TimerProc)(int interval);
|
||||
|
||||
// Interrupt callback functions
|
||||
void vblCallback(void);
|
||||
void sndCallback(void);
|
||||
void refillAudioBuffers(void);
|
||||
|
||||
// External utility functions
|
||||
void enableAudioPlayback(void);
|
||||
void disableAudioPlayback(void);
|
||||
void checkTimers(void);
|
||||
int timer_handler(int t);
|
||||
|
||||
static volatile bool _audioEnabled = false; // Used by interrupt callbacks
|
||||
|
||||
/* Graphic mode identifiers */
|
||||
enum GraphicModeID {
|
||||
OVERS_NTSC_340X240,
|
||||
NORM_NTSC_320X240,
|
||||
NORM_PAL_320X240,
|
||||
OVERS_PAL_340X240,
|
||||
NORM_MPAL_320X240,
|
||||
OVERS_MPAL_340X240
|
||||
};
|
||||
|
||||
class OSystem_N64 : public BaseBackend {
|
||||
protected:
|
||||
Common::SaveFileManager *_savefile;
|
||||
Audio::MixerImpl *_mixer;
|
||||
Common::TimerManager *_timer;
|
||||
FilesystemFactory *_fsFactory;
|
||||
|
||||
struct display_context * _dc; // Display context for N64 on screen buffer switching
|
||||
|
||||
Graphics::Surface _framebuffer;
|
||||
|
||||
uint16 *_offscreen_hic; // Offscreen converted to 16bit surface
|
||||
uint8 *_offscreen_pal; // Offscreen with palette indexes
|
||||
OverlayColor *_overlayBuffer; // Offscreen for the overlay (16 bit)
|
||||
|
||||
uint16 *_screenPalette; // Array for palette entries (256 colors max)
|
||||
uint16 _cursorPalette[256]; // Palette entries for the cursor
|
||||
|
||||
int _graphicMode; // Graphic mode
|
||||
uint16 _screenWidth, _screenHeight;
|
||||
uint16 _gameWidth, _gameHeight;
|
||||
uint16 _frameBufferWidth; // Width of framebuffer in N64 memory
|
||||
uint8 _offscrPixels; // Pixels to skip on each line before start drawing, used to center image
|
||||
uint8 _maxFps;
|
||||
|
||||
int _shakeOffset;
|
||||
|
||||
uint8 *_cursor_pal; // Cursor buffer, palettized
|
||||
bool _cursorPaletteDisabled;
|
||||
bool _dirtyPalette;
|
||||
|
||||
int _cursorWidth, _cursorHeight;
|
||||
int _cursorKeycolor;
|
||||
|
||||
uint16 _overlayHeight, _overlayWidth;
|
||||
bool _overlayVisible;
|
||||
|
||||
bool _mouseVisible;
|
||||
int _mouseX, _mouseY;
|
||||
int _mouseMaxX, _mouseMaxY;
|
||||
int _mouseHotspotX, _mouseHotspotY;
|
||||
|
||||
controller_data_buttons *_ctrlData; // Controller data read from the N64 serial interface
|
||||
|
||||
bool _dirtyOffscreen;
|
||||
|
||||
public:
|
||||
|
||||
/* These have to be accessed by interrupt callbacks */
|
||||
uint16 _audioBufferSize;
|
||||
uint32 _viClockRate; // Clock rate of video system, depending on VI mode
|
||||
|
||||
int _timerCallbackNext;
|
||||
int _timerCallbackTimer;
|
||||
TimerProc _timerCallback;
|
||||
/* *** */
|
||||
|
||||
OSystem_N64();
|
||||
virtual ~OSystem_N64();
|
||||
|
||||
virtual void initBackend();
|
||||
|
||||
virtual bool hasFeature(Feature f);
|
||||
virtual void setFeatureState(Feature f, bool enable);
|
||||
virtual bool getFeatureState(Feature f);
|
||||
virtual const GraphicsMode *getSupportedGraphicsModes() const;
|
||||
virtual int getDefaultGraphicsMode() const;
|
||||
bool setGraphicsMode(const char *name);
|
||||
virtual bool setGraphicsMode(int mode);
|
||||
virtual int getGraphicsMode() const;
|
||||
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
|
||||
virtual int16 getHeight();
|
||||
virtual int16 getWidth();
|
||||
virtual void setPalette(const byte *colors, uint start, uint num);
|
||||
virtual void grabPalette(byte *colors, uint start, uint num);
|
||||
virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual void updateScreen();
|
||||
virtual Graphics::Surface *lockScreen();
|
||||
virtual void unlockScreen();
|
||||
virtual void setShakePos(int shakeOffset);
|
||||
|
||||
virtual void showOverlay();
|
||||
virtual void hideOverlay();
|
||||
virtual void clearOverlay();
|
||||
virtual void grabOverlay(OverlayColor *buf, int pitch);
|
||||
virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual int16 getOverlayHeight();
|
||||
virtual int16 getOverlayWidth();
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const {
|
||||
return Graphics::createPixelFormat<555>();
|
||||
}
|
||||
|
||||
virtual bool showMouse(bool visible);
|
||||
|
||||
virtual void warpMouse(int x, int y);
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
virtual void disableCursorPalette(bool disable);
|
||||
|
||||
virtual bool pollEvent(Common::Event &event);
|
||||
virtual uint32 getMillis();
|
||||
virtual void delayMillis(uint msecs);
|
||||
|
||||
virtual MutexRef createMutex(void);
|
||||
virtual void lockMutex(MutexRef mutex);
|
||||
virtual void unlockMutex(MutexRef mutex);
|
||||
virtual void deleteMutex(MutexRef mutex);
|
||||
|
||||
virtual void quit();
|
||||
|
||||
virtual Common::SaveFileManager *getSavefileManager();
|
||||
virtual Audio::Mixer *getMixer();
|
||||
virtual void getTimeAndDate(TimeDate &t) const;
|
||||
virtual Common::TimerManager *getTimerManager();
|
||||
virtual void setTimerCallback(TimerProc callback, int interval);
|
||||
FilesystemFactory *getFilesystemFactory();
|
||||
|
||||
void rebuildOffscreenGameBuffer(void);
|
||||
void switchGraphicModeId(int mode);
|
||||
|
||||
void setupMixer(void);
|
||||
|
||||
};
|
||||
|
||||
#endif /* __OSYS_N64_H__ */
|
||||
|
804
backends/platform/n64/osys_n64_base.cpp
Normal file
804
backends/platform/n64/osys_n64_base.cpp
Normal file
|
@ -0,0 +1,804 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <romfs.h>
|
||||
|
||||
#include "osys_n64.h"
|
||||
#include "pakfs_save_manager.h"
|
||||
#include "backends/fs/n64/n64-fs-factory.h"
|
||||
|
||||
#define DEFAULT_FRAMEBUFFER_WIDTH 340 // a horizontal resolution of 340 takes into account overscan
|
||||
#define DEFAULT_PIX_SKIP 15
|
||||
|
||||
extern uint8 _romfs; // Defined by linker (used to calculate position of romfs image)
|
||||
|
||||
inline uint16 colBGR888toRGB555(byte r, byte g, byte b);
|
||||
|
||||
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
|
||||
{ "320x240 (PAL) fix overscan", "340x240 PAL", OVERS_PAL_340X240 },
|
||||
{ "320x240 (PAL) overscan", "320x240 PAL", NORM_PAL_320X240 },
|
||||
{ "320x240 (MPAL) fix overscan", "340x240 MPAL", OVERS_MPAL_340X240 },
|
||||
{ "320x240 (MPAL) overscan", "320x240 MPAL", NORM_MPAL_320X240 },
|
||||
{ "340x240 (NTSC) fix overscan", "340x240 NTSC", OVERS_NTSC_340X240 },
|
||||
{ "320x240 (NTSC) overscan", "320x240 NTSC", NORM_NTSC_320X240 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
OSystem_N64::OSystem_N64() {
|
||||
// Enable Mips interrupts
|
||||
set_MI_interrupt(1);
|
||||
|
||||
// Initialize display: NTSC 340x240 (16 bit)
|
||||
initDisplay(NTSC_340X240_16BIT);
|
||||
|
||||
// Prepare virtual text layer for debugging purposes
|
||||
initTextLayer();
|
||||
|
||||
// Init PI interface
|
||||
PI_Init();
|
||||
|
||||
// Init Controller Pak
|
||||
initPakFs();
|
||||
|
||||
// Use the first save pak found
|
||||
uint8 ctrl_num;
|
||||
for (ctrl_num = 0; ctrl_num < 4; ctrl_num++) {
|
||||
int8 pak_type = identifyPak(ctrl_num);
|
||||
if (pak_type == 1) {
|
||||
loadPakData(ctrl_num);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Screen size
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
|
||||
// Game screen size
|
||||
_gameHeight = DEFAULT_SCREEN_WIDTH;
|
||||
_gameWidth = DEFAULT_SCREEN_HEIGHT;
|
||||
|
||||
// Overlay size
|
||||
_overlayWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_overlayHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
|
||||
// Framebuffer width
|
||||
_frameBufferWidth = DEFAULT_FRAMEBUFFER_WIDTH;
|
||||
|
||||
// Pixels to skip
|
||||
_offscrPixels = DEFAULT_PIX_SKIP;
|
||||
|
||||
// Video clock
|
||||
_viClockRate = VI_NTSC_CLOCK;
|
||||
|
||||
_maxFps = N64_NTSC_FPS;
|
||||
|
||||
_overlayVisible = false;
|
||||
|
||||
_shakeOffset = 0;
|
||||
|
||||
// Allocate memory for offscreen buffers
|
||||
_offscreen_hic = (uint16*)memalign(8, DEFAULT_SCREEN_WIDTH * DEFAULT_SCREEN_HEIGHT * 2);
|
||||
_offscreen_pal = (uint8*)memalign(8, DEFAULT_SCREEN_WIDTH * DEFAULT_SCREEN_HEIGHT);
|
||||
_overlayBuffer = (uint16*)memalign(8, DEFAULT_SCREEN_WIDTH * DEFAULT_SCREEN_HEIGHT * sizeof(OverlayColor));
|
||||
|
||||
_cursor_pal = NULL;
|
||||
|
||||
_cursorWidth = -1;
|
||||
_cursorHeight = -1;
|
||||
_cursorKeycolor = -1;
|
||||
_mouseHotspotX = _mouseHotspotY = -1;
|
||||
|
||||
// Clean offscreen buffers
|
||||
memset(_offscreen_hic, 0, _screenWidth * _screenHeight * 2);
|
||||
memset(_offscreen_pal, 0, _screenWidth * _screenHeight);
|
||||
memset(_overlayBuffer, 0, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
|
||||
|
||||
// Default graphic mode
|
||||
_graphicMode = OVERS_NTSC_340X240;
|
||||
|
||||
// Clear palette array
|
||||
_screenPalette = (uint16*)memalign(8, 256 * sizeof(uint16));
|
||||
memset(_screenPalette, 0, 256 * sizeof(uint16));
|
||||
memset(_cursorPalette, 0, 256 * sizeof(uint16));
|
||||
|
||||
_dirtyPalette = false;
|
||||
_cursorPaletteDisabled = false;
|
||||
|
||||
_audioEnabled = false;
|
||||
|
||||
// Initialize ROMFS access interface
|
||||
initRomFSmanager((uint8*)(((uint32)&_romfs + (uint32)0xc00) | (uint32)0xB0000000));
|
||||
|
||||
// Register vblank callback
|
||||
registerVIhandler(vblCallback);
|
||||
|
||||
_mouseVisible = false;
|
||||
|
||||
_mouseX = _overlayWidth / 2;
|
||||
_mouseY = _overlayHeight / 2;
|
||||
_mouseMaxX = _overlayWidth;
|
||||
_mouseMaxY = _overlayHeight;
|
||||
|
||||
_savefile = 0;
|
||||
_mixer = 0;
|
||||
_timer = 0;
|
||||
|
||||
_dirtyOffscreen = false;
|
||||
|
||||
_ctrlData = (controller_data_buttons*)memalign(8, sizeof(controller_data_buttons));
|
||||
|
||||
_fsFactory = new N64FilesystemFactory();
|
||||
|
||||
}
|
||||
|
||||
OSystem_N64::~OSystem_N64() {
|
||||
delete _savefile;
|
||||
delete _mixer;
|
||||
delete _timer;
|
||||
delete _fsFactory;
|
||||
}
|
||||
|
||||
void OSystem_N64::initBackend() {
|
||||
ConfMan.setInt("autosave_period", 0);
|
||||
ConfMan.setBool("FM_high_quality", false);
|
||||
ConfMan.setBool("FM_medium_quality", true);
|
||||
ConfMan.set("gui_theme", "modern"); // In case of modern theme being present, use it.
|
||||
|
||||
_savefile = new PAKSaveManager();
|
||||
|
||||
_mixer = new Audio::MixerImpl(this);
|
||||
_mixer->setReady(false);
|
||||
|
||||
_timer = new DefaultTimerManager();
|
||||
|
||||
setTimerCallback(&timer_handler, 10);
|
||||
|
||||
setupMixer();
|
||||
|
||||
OSystem::initBackend();
|
||||
|
||||
}
|
||||
|
||||
bool OSystem_N64::hasFeature(Feature f) {
|
||||
return (f == kFeatureCursorHasPalette);
|
||||
}
|
||||
|
||||
void OSystem_N64::setFeatureState(Feature f, bool enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool OSystem_N64::getFeatureState(Feature f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const OSystem::GraphicsMode* OSystem_N64::getSupportedGraphicsModes() const {
|
||||
return s_supportedGraphicsModes;
|
||||
}
|
||||
|
||||
|
||||
int OSystem_N64::getDefaultGraphicsMode() const {
|
||||
return OVERS_NTSC_340X240;
|
||||
}
|
||||
|
||||
bool OSystem_N64::setGraphicsMode(const char *mode) {
|
||||
int i = 0;
|
||||
while (s_supportedGraphicsModes[i].name) {
|
||||
if (!strcmpi(s_supportedGraphicsModes[i].name, mode)) {
|
||||
_graphicMode = s_supportedGraphicsModes[i].id;
|
||||
|
||||
switchGraphicModeId(_graphicMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSystem_N64::setGraphicsMode(int mode) {
|
||||
_graphicMode = mode;
|
||||
switchGraphicModeId(_graphicMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSystem_N64::switchGraphicModeId(int mode) {
|
||||
switch (mode) {
|
||||
case NORM_PAL_320X240:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_PAL_CLOCK;
|
||||
_maxFps = N64_PAL_FPS;
|
||||
initDisplay(PAL_320X240_16BIT);
|
||||
_frameBufferWidth = 320;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = 0;
|
||||
_graphicMode = NORM_PAL_320X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
|
||||
case OVERS_PAL_340X240:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_PAL_CLOCK;
|
||||
_maxFps = N64_PAL_FPS;
|
||||
initDisplay(PAL_340X240_16BIT);
|
||||
_frameBufferWidth = DEFAULT_FRAMEBUFFER_WIDTH;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = DEFAULT_PIX_SKIP;
|
||||
_graphicMode = OVERS_PAL_340X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
|
||||
case NORM_MPAL_320X240:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_MPAL_CLOCK;
|
||||
_maxFps = N64_NTSC_FPS;
|
||||
initDisplay(MPAL_320X240_16BIT);
|
||||
_frameBufferWidth = 320;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = 0;
|
||||
_graphicMode = NORM_MPAL_320X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
|
||||
case OVERS_MPAL_340X240:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_MPAL_CLOCK;
|
||||
_maxFps = N64_NTSC_FPS;
|
||||
initDisplay(MPAL_340X240_16BIT);
|
||||
_frameBufferWidth = DEFAULT_FRAMEBUFFER_WIDTH;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = DEFAULT_PIX_SKIP;
|
||||
_graphicMode = OVERS_MPAL_340X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
|
||||
case NORM_NTSC_320X240:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_NTSC_CLOCK;
|
||||
_maxFps = N64_NTSC_FPS;
|
||||
initDisplay(NTSC_320X240_16BIT);
|
||||
_frameBufferWidth = 320;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = 0;
|
||||
_graphicMode = NORM_NTSC_320X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
|
||||
case OVERS_NTSC_340X240:
|
||||
default:
|
||||
disableAudioPlayback();
|
||||
_viClockRate = VI_NTSC_CLOCK;
|
||||
_maxFps = N64_NTSC_FPS;
|
||||
initDisplay(NTSC_340X240_16BIT);
|
||||
_frameBufferWidth = DEFAULT_FRAMEBUFFER_WIDTH;
|
||||
_screenWidth = DEFAULT_SCREEN_WIDTH;
|
||||
_screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
_offscrPixels = DEFAULT_PIX_SKIP;
|
||||
_graphicMode = OVERS_NTSC_340X240;
|
||||
enableAudioPlayback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int OSystem_N64::getGraphicsMode() const {
|
||||
return _graphicMode;
|
||||
}
|
||||
|
||||
void OSystem_N64::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
|
||||
_gameWidth = width;
|
||||
_gameHeight = height;
|
||||
|
||||
if (_gameWidth > _screenWidth)
|
||||
_gameWidth = _screenWidth;
|
||||
if (_gameHeight > _screenHeight)
|
||||
_gameHeight = _screenHeight;
|
||||
|
||||
_mouseMaxX = _gameWidth;
|
||||
_mouseMaxY = _gameHeight;
|
||||
}
|
||||
|
||||
int16 OSystem_N64::getHeight() {
|
||||
return _screenHeight;
|
||||
}
|
||||
|
||||
int16 OSystem_N64::getWidth() {
|
||||
return _screenWidth;
|
||||
}
|
||||
|
||||
void OSystem_N64::setPalette(const byte *colors, uint start, uint num) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
uint8 c[4];
|
||||
_screenPalette[start + i] = colBGR888toRGB555(colors[2], colors[1], colors[0]);
|
||||
colors += 4;
|
||||
}
|
||||
|
||||
_dirtyPalette = true;
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::rebuildOffscreenGameBuffer(void) {
|
||||
// Regenerate hi-color offscreen buffer
|
||||
uint32 two_col_hi;
|
||||
uint32 four_col_pal;
|
||||
for (int h = 0; h < _gameHeight; h++)
|
||||
for (int w = 0; w < _gameWidth; w += 4) {
|
||||
four_col_pal = *(uint32*)(_offscreen_pal + ((h * _screenWidth) + w));
|
||||
|
||||
two_col_hi = 0;
|
||||
two_col_hi = _screenPalette[((four_col_pal >> (8 * 3)) & 0xFF)] | (two_col_hi << (16 * 0));
|
||||
two_col_hi = _screenPalette[((four_col_pal >> (8 * 2)) & 0xFF)] | (two_col_hi << (16 * 1));
|
||||
|
||||
*(uint32*)(_offscreen_hic + (h * _screenWidth) + w + 0) = two_col_hi;
|
||||
|
||||
two_col_hi = 0;
|
||||
two_col_hi = _screenPalette[((four_col_pal >> (8 * 1)) & 0xFF)] | (two_col_hi << (16 * 0));
|
||||
two_col_hi = _screenPalette[((four_col_pal >> (8 * 0)) & 0xFF)] | (two_col_hi << (16 * 1));
|
||||
|
||||
*(uint32*)(_offscreen_hic + (h * _screenWidth) + w + 2) = two_col_hi;
|
||||
}
|
||||
}
|
||||
|
||||
void OSystem_N64::grabPalette(byte *colors, uint start, uint num) {
|
||||
uint32 i;
|
||||
uint16 color;
|
||||
|
||||
for (i = start; i < start + num; i++) {
|
||||
color = _screenPalette[i];
|
||||
|
||||
// Color format on the n64 is RGB - 1555
|
||||
*colors++ = ((color & 0x1F) << 3);
|
||||
*colors++ = (((color >> 5) & 0x1F) << 3);
|
||||
*colors++ = (((color >> 10) & 0x1F) << 3);
|
||||
*colors++ = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
_cursorPalette[start + i] = colBGR888toRGB555(colors[2], colors[1], colors[0]);
|
||||
colors += 4;
|
||||
}
|
||||
|
||||
_cursorPaletteDisabled = false;
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::disableCursorPalette(bool disable) {
|
||||
_cursorPaletteDisabled = disable;
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
|
||||
//Clip the coordinates
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
buf -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
buf -= y * pitch;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (w > _screenWidth - x) {
|
||||
w = _screenWidth - x;
|
||||
}
|
||||
|
||||
if (h > _screenHeight - y) {
|
||||
h = _screenHeight - y;
|
||||
}
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
uint8 *dst_pal = _offscreen_pal + ((y * _screenWidth) + x);
|
||||
uint16 *dst_hicol = _offscreen_hic + ((y * _screenWidth) + x);
|
||||
|
||||
do {
|
||||
for (int hor = 0; hor < w; hor++) {
|
||||
if (dst_pal[hor] != buf[hor]) {
|
||||
uint16 color = _screenPalette[buf[hor]];
|
||||
dst_hicol[hor] = color; // Save image converted to 16-bit
|
||||
dst_pal[hor] = buf[hor]; // Save palettized display
|
||||
}
|
||||
}
|
||||
|
||||
buf += pitch;
|
||||
dst_pal += _screenWidth;
|
||||
dst_hicol += _screenWidth;
|
||||
} while (--h);
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::updateScreen() {
|
||||
#ifdef LIMIT_FPS
|
||||
static uint32 _lastScreenUpdate = 0;
|
||||
uint32 now = getMillis();
|
||||
if (now - _lastScreenUpdate < 1000 / _maxFps)
|
||||
return;
|
||||
|
||||
_lastScreenUpdate = now;
|
||||
#endif
|
||||
|
||||
// Check if audio buffer needs refill
|
||||
// Done here because this gets called regularly
|
||||
refillAudioBuffers();
|
||||
|
||||
if (!_dirtyOffscreen && !_dirtyPalette) return; // The offscreen is clean
|
||||
|
||||
uint8 skip_lines = (_screenHeight - _gameHeight) / 4;
|
||||
uint8 skip_pixels = (_screenWidth - _gameWidth) / 2; // Center horizontally the image
|
||||
|
||||
if (_dirtyPalette)
|
||||
rebuildOffscreenGameBuffer();
|
||||
|
||||
while (!(_dc = lockDisplay()));
|
||||
|
||||
uint16 *overlay_framebuffer = (uint16*)_dc->conf.framebuffer; // Current screen framebuffer
|
||||
uint16 *game_framebuffer = overlay_framebuffer + (_frameBufferWidth * skip_lines * 2); // Skip some lines to center the image vertically
|
||||
|
||||
uint16 currentHeight;
|
||||
uint16 *tmpDst;
|
||||
uint16 *tmpSrc;
|
||||
|
||||
// Copy the game buffer to screen
|
||||
if (!_overlayVisible) {
|
||||
tmpDst = game_framebuffer;
|
||||
tmpSrc = _offscreen_hic + (_shakeOffset * _screenWidth);
|
||||
for (currentHeight = _shakeOffset; currentHeight < _gameHeight; currentHeight++) {
|
||||
memcpy((tmpDst + skip_pixels + _offscrPixels), tmpSrc, _screenWidth * 2);
|
||||
tmpDst += _frameBufferWidth;
|
||||
tmpSrc += _screenWidth;
|
||||
}
|
||||
|
||||
uint16 _clearLines = _shakeOffset; // When shaking we must take care of remaining lines to clear
|
||||
while (_clearLines--) {
|
||||
memset(tmpDst + skip_pixels + _offscrPixels, 0, _screenWidth * 2);
|
||||
tmpDst += _frameBufferWidth;
|
||||
}
|
||||
} else { // If the overlay is enabled, draw it on top of game screen
|
||||
tmpDst = overlay_framebuffer;
|
||||
tmpSrc = _overlayBuffer;
|
||||
for (currentHeight = 0; currentHeight < _overlayHeight; currentHeight++) {
|
||||
memcpy((tmpDst + _offscrPixels), tmpSrc, _overlayWidth * 2);
|
||||
tmpDst += _frameBufferWidth;
|
||||
tmpSrc += _overlayWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw mouse cursor
|
||||
if ((_mouseVisible || _overlayVisible) && _cursorHeight > 0 && _cursorWidth > 0) {
|
||||
uint16 *mouse_framebuffer;
|
||||
uint16 horiz_pix_skip = 0;
|
||||
|
||||
if (_overlayVisible) {
|
||||
mouse_framebuffer = overlay_framebuffer;
|
||||
} else {
|
||||
mouse_framebuffer = game_framebuffer;
|
||||
horiz_pix_skip = skip_pixels;
|
||||
}
|
||||
|
||||
int mX = _mouseX - _mouseHotspotX;
|
||||
int mY = _mouseY - _mouseHotspotY;
|
||||
|
||||
uint16 *_cursorSource = _cursorPaletteDisabled ? _screenPalette : _cursorPalette;
|
||||
for (int h = 0; h < _cursorHeight; h++)
|
||||
for (int w = 0; w < _cursorWidth; w++) {
|
||||
uint8 index = _cursor_pal[(h * _cursorWidth) + w];
|
||||
|
||||
// Draw pixel
|
||||
if ((index != _cursorKeycolor) && ((mY + h) >= 0) && ((mY + h) < _mouseMaxY) && ((mX + w) >= 0) && ((mX + w) < _mouseMaxX))
|
||||
mouse_framebuffer[((mY + h) * _frameBufferWidth) + ((mX + w) + _offscrPixels + horiz_pix_skip)] = _cursorSource[index];
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _ENABLE_DEBUG_
|
||||
showDisplay(_dc);
|
||||
#else
|
||||
showDisplayAndText(_dc);
|
||||
#endif
|
||||
|
||||
_dc = NULL;
|
||||
_dirtyOffscreen = false;
|
||||
_dirtyPalette = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics::Surface *OSystem_N64::lockScreen() {
|
||||
_framebuffer.pixels = _offscreen_pal;
|
||||
_framebuffer.w = _gameWidth;
|
||||
_framebuffer.h = _gameHeight;
|
||||
_framebuffer.pitch = _screenWidth;
|
||||
_framebuffer.bytesPerPixel = 1;
|
||||
|
||||
return &_framebuffer;
|
||||
}
|
||||
|
||||
void OSystem_N64::unlockScreen() {
|
||||
_dirtyPalette = true;
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::setShakePos(int shakeOffset) {
|
||||
_shakeOffset = shakeOffset;
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::showOverlay() {
|
||||
// Change min/max mouse coords
|
||||
_mouseMaxX = _overlayWidth;
|
||||
_mouseMaxY = _overlayHeight;
|
||||
|
||||
// Relocate the mouse cursor given the new limitations
|
||||
warpMouse(_mouseX, _mouseY);
|
||||
|
||||
_overlayVisible = true;
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::hideOverlay() {
|
||||
// Change min/max mouse coords
|
||||
_mouseMaxX = _gameWidth;
|
||||
_mouseMaxY = _gameHeight;
|
||||
|
||||
// Relocate the mouse cursor given the new limitations
|
||||
warpMouse(_mouseX, _mouseY);
|
||||
|
||||
_overlayVisible = false;
|
||||
|
||||
// Clear double buffered display
|
||||
clearAllVideoBuffers();
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::clearOverlay() {
|
||||
memset(_overlayBuffer, 0, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
|
||||
|
||||
uint8 skip_lines = (_screenHeight - _gameHeight) / 4;
|
||||
uint8 skip_pixels = (_screenWidth - _gameWidth) / 2; // Center horizontally the image
|
||||
|
||||
uint16 *tmpDst = _overlayBuffer + (_overlayWidth * skip_lines * 2);
|
||||
uint16 *tmpSrc = _offscreen_hic + (_shakeOffset * _screenWidth);
|
||||
for (uint16 currentHeight = _shakeOffset; currentHeight < _gameHeight; currentHeight++) {
|
||||
memcpy((tmpDst + skip_pixels), tmpSrc, _gameWidth * 2);
|
||||
tmpDst += _overlayWidth;
|
||||
tmpSrc += _screenWidth;
|
||||
}
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::grabOverlay(OverlayColor *buf, int pitch) {
|
||||
int h = _overlayHeight;
|
||||
OverlayColor *src = _overlayBuffer;
|
||||
|
||||
do {
|
||||
memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
|
||||
src += _overlayWidth;
|
||||
buf += pitch;
|
||||
} while (--h);
|
||||
}
|
||||
|
||||
void OSystem_N64::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
|
||||
//Clip the coordinates
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
buf -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
buf -= y * pitch;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (w > _overlayWidth - x) {
|
||||
w = _overlayWidth - x;
|
||||
}
|
||||
|
||||
if (h > _overlayHeight - y) {
|
||||
h = _overlayHeight - y;
|
||||
}
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
|
||||
OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);
|
||||
|
||||
if (_overlayWidth == pitch && pitch == w) {
|
||||
memcpy(dst, buf, h * w * sizeof(OverlayColor));
|
||||
} else {
|
||||
do {
|
||||
memcpy(dst, buf, w * sizeof(OverlayColor));
|
||||
buf += pitch;
|
||||
dst += _overlayWidth;
|
||||
} while (--h);
|
||||
}
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int16 OSystem_N64::getOverlayHeight() {
|
||||
return _overlayHeight;
|
||||
}
|
||||
|
||||
int16 OSystem_N64::getOverlayWidth() {
|
||||
return _overlayWidth;
|
||||
}
|
||||
|
||||
|
||||
bool OSystem_N64::showMouse(bool visible) {
|
||||
bool last = _mouseVisible;
|
||||
_mouseVisible = visible;
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
void OSystem_N64::warpMouse(int x, int y) {
|
||||
|
||||
if (x < 0)
|
||||
_mouseX = 0;
|
||||
else if (x >= _mouseMaxX)
|
||||
_mouseX = _mouseMaxX - 1;
|
||||
else
|
||||
_mouseX = x;
|
||||
|
||||
if (y < 0)
|
||||
_mouseY = 0;
|
||||
else if (y >= _mouseMaxY)
|
||||
_mouseY = _mouseMaxY - 1;
|
||||
else
|
||||
_mouseY = y;
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
}
|
||||
|
||||
void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
||||
if (!w || !h) return;
|
||||
|
||||
_mouseHotspotX = hotspotX;
|
||||
_mouseHotspotY = hotspotY;
|
||||
|
||||
if (_cursor_pal && ((w != _cursorWidth) || (h != _cursorHeight))) {
|
||||
free(_cursor_pal);
|
||||
_cursor_pal = NULL;
|
||||
}
|
||||
|
||||
if (!_cursor_pal) {
|
||||
_cursor_pal = (uint8*)malloc(w * h);
|
||||
}
|
||||
|
||||
_cursorWidth = w;
|
||||
_cursorHeight = h;
|
||||
|
||||
memcpy(_cursor_pal, buf, w * h); // Copy the palettized cursor
|
||||
|
||||
_cursorKeycolor = keycolor & 0xFF;
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 OSystem_N64::getMillis() {
|
||||
return getMilliTick();
|
||||
}
|
||||
|
||||
void OSystem_N64::delayMillis(uint msecs) {
|
||||
delay(msecs);
|
||||
}
|
||||
|
||||
OSystem::MutexRef OSystem_N64::createMutex(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void OSystem_N64::lockMutex(MutexRef mutex) {
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::unlockMutex(MutexRef mutex) {
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::deleteMutex(MutexRef mutex) {
|
||||
return;
|
||||
}
|
||||
|
||||
void OSystem_N64::quit() {
|
||||
// Not much to do...
|
||||
return;
|
||||
}
|
||||
|
||||
Common::SaveFileManager *OSystem_N64::getSavefileManager() {
|
||||
assert(_savefile);
|
||||
return _savefile;
|
||||
}
|
||||
|
||||
Audio::Mixer *OSystem_N64::getMixer() {
|
||||
assert(_mixer);
|
||||
return _mixer;
|
||||
}
|
||||
|
||||
Common::TimerManager *OSystem_N64::getTimerManager() {
|
||||
assert(_timer);
|
||||
return _timer;
|
||||
}
|
||||
|
||||
void OSystem_N64::getTimeAndDate(TimeDate &t) const {
|
||||
// No clock inside the N64
|
||||
// TODO: use getMillis to provide some kind of time-counting feature?
|
||||
t.tm_sec = 0;
|
||||
t.tm_min = 0;
|
||||
t.tm_hour = 0;
|
||||
t.tm_mday = 0;
|
||||
t.tm_mon = 0;
|
||||
t.tm_year = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FilesystemFactory *OSystem_N64::getFilesystemFactory() {
|
||||
return _fsFactory;
|
||||
}
|
||||
|
||||
void OSystem_N64::setTimerCallback(TimerProc callback, int interval) {
|
||||
if (callback != NULL) {
|
||||
_timerCallbackTimer = interval;
|
||||
_timerCallbackNext = getMillis() + interval;
|
||||
_timerCallback = callback;
|
||||
} else
|
||||
_timerCallback = NULL;
|
||||
}
|
||||
|
||||
void OSystem_N64::setupMixer(void) {
|
||||
enableAudioPlayback();
|
||||
}
|
||||
|
||||
inline uint16 colBGR888toRGB555(byte r, byte g, byte b) {
|
||||
return ((r >> 3) << 1) | ((g >> 3) << 6) | ((b >> 3) << 11);
|
||||
}
|
||||
|
243
backends/platform/n64/osys_n64_events.cpp
Normal file
243
backends/platform/n64/osys_n64_events.cpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "osys_n64.h"
|
||||
|
||||
// Pad buttons
|
||||
#define START_BUTTON(a) (a & 0x1000)
|
||||
#define A_BUTTON(a) (a & 0x8000)
|
||||
#define B_BUTTON(a) (a & 0x4000)
|
||||
#define Z_BUTTON(a) (a & 0x2000)
|
||||
|
||||
// Triggers
|
||||
#define TL_BUTTON(a) (a & 0x0020)
|
||||
#define TR_BUTTON(a) (a & 0x0010)
|
||||
|
||||
// D-Pad
|
||||
#define DL_BUTTON(a) (a & 0x0200)
|
||||
#define DR_BUTTON(a) (a & 0x0100)
|
||||
#define DU_BUTTON(a) (a & 0x0800)
|
||||
#define DD_BUTTON(a) (a & 0x0400)
|
||||
|
||||
// Yellow C buttons
|
||||
#define CL_BUTTON(a) (a & 0x0002)
|
||||
#define CR_BUTTON(a) (a & 0x0001)
|
||||
#define CU_BUTTON(a) (a & 0x0008)
|
||||
#define CD_BUTTON(a) (a & 0x0004)
|
||||
|
||||
#define PAD_DEADZONE 5
|
||||
#define PAD_ACCELERATION 10
|
||||
#define PAD_CHECK_TIME 40
|
||||
|
||||
bool OSystem_N64::pollEvent(Common::Event &event) {
|
||||
// Check Timers. Not the best place, but checking in interrupts proved to be unsafe
|
||||
checkTimers();
|
||||
|
||||
// Refill audio buffers, doing this inside interrupts could be harmful
|
||||
refillAudioBuffers();
|
||||
|
||||
// Read current controller status
|
||||
controller_Read_Buttons(_ctrlData);
|
||||
|
||||
static uint16 oldButtons = 0; // old button data... used for button press/release
|
||||
uint16 newButtons = _ctrlData->c[0].buttons; // Read from controller 0
|
||||
|
||||
bool buttonPressed = false;
|
||||
static bool left_digital = false;
|
||||
static bool right_digital = false;
|
||||
static bool up_digital = false;
|
||||
static bool down_digital = false;
|
||||
|
||||
int8 analogX = (_ctrlData->c[0].throttle >> 8) & 0xFF;
|
||||
int8 analogY = (_ctrlData->c[0].throttle >> 0) & 0xFF;
|
||||
|
||||
if (newButtons != oldButtons) {
|
||||
if (DL_BUTTON(newButtons) && !DL_BUTTON(oldButtons)) // Pressed LEFT
|
||||
left_digital = true;
|
||||
else if (!DL_BUTTON(newButtons) && DL_BUTTON(oldButtons)) // Released LEFT
|
||||
left_digital = false;
|
||||
|
||||
if (DR_BUTTON(newButtons) && !DR_BUTTON(oldButtons)) // Pressed RIGHT
|
||||
right_digital = true;
|
||||
else if (!DR_BUTTON(newButtons) && DR_BUTTON(oldButtons)) // Released RIGHT
|
||||
right_digital = false;
|
||||
|
||||
if (DU_BUTTON(newButtons) && !DU_BUTTON(oldButtons)) // Pressed UP
|
||||
up_digital = true;
|
||||
else if (!DU_BUTTON(newButtons) && DU_BUTTON(oldButtons)) // Released UP
|
||||
up_digital = false;
|
||||
|
||||
if (DD_BUTTON(newButtons) && !DD_BUTTON(oldButtons)) // Pressed DOWN
|
||||
down_digital = true;
|
||||
else if (!DD_BUTTON(newButtons) && DD_BUTTON(oldButtons)) // Released DOWN
|
||||
down_digital = false;
|
||||
|
||||
if (B_BUTTON(newButtons) && !B_BUTTON(oldButtons)) { // Pressed B - Right Mouse Button
|
||||
buttonPressed = true;
|
||||
event.type = Common::EVENT_RBUTTONDOWN;
|
||||
} else if (!B_BUTTON(newButtons) && B_BUTTON(oldButtons)) { // Released B
|
||||
buttonPressed = true;
|
||||
event.type = Common::EVENT_RBUTTONUP;
|
||||
} else if (A_BUTTON(newButtons) && !A_BUTTON(oldButtons)) { // Pressed A - Period
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_PERIOD;
|
||||
event.kbd.ascii = '.';
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!A_BUTTON(newButtons) && A_BUTTON(oldButtons)) { // Released A
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_PERIOD;
|
||||
event.kbd.ascii = '.';
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (START_BUTTON(newButtons) && !START_BUTTON(oldButtons)) { // Pressed START - F5
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_F5;
|
||||
event.kbd.ascii = Common::ASCII_F5;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!START_BUTTON(newButtons) && START_BUTTON(oldButtons)) { // Released START
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_F5;
|
||||
event.kbd.ascii = Common::ASCII_F5;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (CU_BUTTON(newButtons) && !CU_BUTTON(oldButtons)) { // Pressed Yellow Up - UP
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_UP;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!CU_BUTTON(newButtons) && CU_BUTTON(oldButtons)) { // Released Yellow Up
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_UP;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (CD_BUTTON(newButtons) && !CD_BUTTON(oldButtons)) { // Pressed Yellow Down - DOWN
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_DOWN;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!CD_BUTTON(newButtons) && CD_BUTTON(oldButtons)) { // Released Yellow Down
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_DOWN;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (CL_BUTTON(newButtons) && !CL_BUTTON(oldButtons)) { // Pressed Yellow Left - LEFT
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_LEFT;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!CL_BUTTON(newButtons) && CL_BUTTON(oldButtons)) { // Released Yellow Left
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_LEFT;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (CR_BUTTON(newButtons) && !CR_BUTTON(oldButtons)) { // Pressed Yellow Right - RIGHT
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_RIGHT;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!CR_BUTTON(newButtons) && CR_BUTTON(oldButtons)) { // Released Yellow Right
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_RIGHT;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (TL_BUTTON(newButtons) && !TL_BUTTON(oldButtons)) { // Pressed Trigger Left - ESC
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_ESCAPE;
|
||||
event.kbd.ascii = 27;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!TL_BUTTON(newButtons) && TL_BUTTON(oldButtons)) { // Released Trigger Left
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_ESCAPE;
|
||||
event.kbd.ascii = 27;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (TR_BUTTON(newButtons) && !TR_BUTTON(oldButtons)) { // Pressed Trigger Right - F7
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_F7;
|
||||
event.kbd.ascii = Common::ASCII_F7;
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
} else if (!TR_BUTTON(newButtons) && TR_BUTTON(oldButtons)) { // Released Trigger Right
|
||||
buttonPressed = true;
|
||||
event.kbd.keycode = Common::KEYCODE_F7;
|
||||
event.kbd.ascii = Common::ASCII_F7;
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
} else if (Z_BUTTON(newButtons) && !Z_BUTTON(oldButtons)) { // Pressed Z - Left Mouse Button
|
||||
buttonPressed = true;
|
||||
event.type = Common::EVENT_LBUTTONDOWN;
|
||||
} else if (!Z_BUTTON(newButtons) && Z_BUTTON(oldButtons)) { // Released Z
|
||||
buttonPressed = true;
|
||||
event.type = Common::EVENT_LBUTTONUP;
|
||||
}
|
||||
|
||||
oldButtons = newButtons; // Save current button status
|
||||
|
||||
if (buttonPressed) {
|
||||
event.mouse.x = _mouseX;
|
||||
event.mouse.y = _mouseY;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 _lastPadCheck = 0;
|
||||
uint32 curTime = getMillis();
|
||||
|
||||
if ((curTime - _lastPadCheck) > PAD_CHECK_TIME) {
|
||||
_lastPadCheck = curTime;
|
||||
|
||||
int32 mx = _mouseX;
|
||||
int32 my = _mouseY;
|
||||
|
||||
if (left_digital || right_digital || up_digital || down_digital) {
|
||||
if (left_digital)
|
||||
mx -= 5;
|
||||
else if (right_digital)
|
||||
mx += 5;
|
||||
if (up_digital)
|
||||
my -= 5;
|
||||
else if (down_digital)
|
||||
my += 5;
|
||||
}
|
||||
|
||||
if (abs(analogX) > PAD_DEADZONE)
|
||||
mx += analogX / (PAD_ACCELERATION - (abs(analogX) / 20));
|
||||
|
||||
if (abs(analogY) > PAD_DEADZONE)
|
||||
my -= analogY / (PAD_ACCELERATION - (abs(analogY) / 20));
|
||||
|
||||
if (mx < 0)
|
||||
mx = 0;
|
||||
|
||||
if (mx >= _mouseMaxX)
|
||||
mx = _mouseMaxX - 1;
|
||||
|
||||
if (my < 0)
|
||||
my = 0;
|
||||
|
||||
if (my >= _mouseMaxY)
|
||||
my = _mouseMaxY - 1;
|
||||
|
||||
if ((mx != _mouseX) || (my != _mouseY)) {
|
||||
|
||||
event.type = Common::EVENT_MOUSEMOVE;
|
||||
event.mouse.x = _mouseX = mx;
|
||||
event.mouse.y = _mouseY = my;
|
||||
|
||||
_dirtyOffscreen = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
123
backends/platform/n64/osys_n64_utilities.cpp
Normal file
123
backends/platform/n64/osys_n64_utilities.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "osys_n64.h"
|
||||
|
||||
void checkTimers(void) {
|
||||
OSystem_N64 *osys = (OSystem_N64*)g_system;
|
||||
|
||||
uint32 curTime = osys->getMillis();
|
||||
|
||||
// Timer checking & firing
|
||||
if (osys->_timerCallback && (curTime >= osys->_timerCallbackNext)) {
|
||||
osys->_timerCallback(osys->_timerCallbackTimer);
|
||||
osys->_timerCallbackNext = curTime + osys->_timerCallbackTimer;
|
||||
}
|
||||
}
|
||||
|
||||
void disableAudioPlayback(void) {
|
||||
if (!_audioEnabled) return;
|
||||
|
||||
_audioEnabled = false;
|
||||
|
||||
OSystem_N64 *osys = (OSystem_N64*)g_system;
|
||||
Audio::MixerImpl *_localmixer = (Audio::MixerImpl*)osys->getMixer();
|
||||
|
||||
while (AI_busy()); // Wait for audio to stop
|
||||
}
|
||||
|
||||
void enableAudioPlayback(void) {
|
||||
static bool _firstRun = true;
|
||||
|
||||
OSystem_N64 *osys = (OSystem_N64*)g_system;
|
||||
Audio::MixerImpl *_localmixer = (Audio::MixerImpl*)osys->getMixer();
|
||||
|
||||
uint32 samples = 4096; // 4096 bytes -> 2048 samples.
|
||||
|
||||
initAudioInterface(osys->_viClockRate, DEFAULT_SOUND_SAMPLE_RATE, 16, samples);
|
||||
osys->_audioBufferSize = getAIBufferSize();
|
||||
|
||||
if (_firstRun) {
|
||||
_localmixer->setOutputRate(DEFAULT_SOUND_SAMPLE_RATE);
|
||||
_localmixer->setReady(true);
|
||||
_firstRun = false;
|
||||
}
|
||||
|
||||
disable_interrupts();
|
||||
|
||||
_audioEnabled = true;
|
||||
|
||||
sndCallback();
|
||||
sndCallback();
|
||||
|
||||
registerAIhandler(sndCallback); // Lib checks if i try to register it multiple times
|
||||
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
static volatile Uint32 _requiredSoundSlots = 0;
|
||||
|
||||
void vblCallback(void) {
|
||||
// Switch display buffer
|
||||
switchDisplayBuffer();
|
||||
|
||||
#if 1
|
||||
// If audio buffer got depleted, refill it.
|
||||
if (_audioEnabled && !AI_busy() && !_requiredSoundSlots) {
|
||||
sndCallback();
|
||||
sndCallback();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void sndCallback() {
|
||||
// Signal that an audio buffer finished playing and that we need more samples
|
||||
if (_requiredSoundSlots < 2)
|
||||
_requiredSoundSlots++;
|
||||
}
|
||||
|
||||
void refillAudioBuffers(void) {
|
||||
if (!_audioEnabled) return;
|
||||
|
||||
OSystem_N64 *osys = (OSystem_N64*)g_system;
|
||||
byte *sndBuf;
|
||||
Audio::MixerImpl *_localmixer = (Audio::MixerImpl*)osys->getMixer();
|
||||
|
||||
while (_requiredSoundSlots) {
|
||||
sndBuf = (byte*)getAIBuffer();
|
||||
|
||||
_localmixer->mixCallback((byte*)sndBuf, osys->_audioBufferSize);
|
||||
|
||||
putAIBuffer();
|
||||
|
||||
_requiredSoundSlots--;
|
||||
}
|
||||
}
|
||||
|
||||
int timer_handler(int t) {
|
||||
DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
|
||||
tm->handler();
|
||||
return t;
|
||||
}
|
||||
|
13
backends/platform/n64/pad_rom.sh
Normal file
13
backends/platform/n64/pad_rom.sh
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
TARGET="scummvm"
|
||||
BASESIZE=2097152
|
||||
|
||||
CARTSIZE=`ls -l $TARGET.v64 | cut -d" " -f5`
|
||||
|
||||
REMAINDER=`echo $CARTSIZE % $BASESIZE | bc`
|
||||
REMAINDER=`echo $BASESIZE - $REMAINDER | bc`
|
||||
CARTSIZE=`echo $CARTSIZE + $REMAINDER | bc`
|
||||
|
||||
ucon64 -q --n64 --v64 --chk --padn=$CARTSIZE $TARGET.v64
|
||||
|
92
backends/platform/n64/pakfs_save_manager.cpp
Normal file
92
backends/platform/n64/pakfs_save_manager.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <n64utils.h>
|
||||
#include "pakfs_save_manager.h"
|
||||
|
||||
static bool matches(const char *glob, const char *name);
|
||||
|
||||
bool deleteSaveGame(const char *filename) {
|
||||
int res = removeFileOnPak(filename);
|
||||
flushCurrentPakData();
|
||||
|
||||
return (res == 0);
|
||||
}
|
||||
|
||||
uint32 InPAKSave::read(void *buf, uint32 cnt) {
|
||||
return pakfs_read(buf, 1, cnt, fd);
|
||||
}
|
||||
|
||||
bool InPAKSave::seek(int32 offs, int whence) {
|
||||
pakfs_seek(fd, offs, whence);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InPAKSave::skip(uint32 offset) {
|
||||
pakfs_seek(fd, offset, SEEK_CUR);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 OutPAKSave::write(const void *buf, uint32 cnt) {
|
||||
return pakfs_write(buf, 1, cnt, fd);
|
||||
}
|
||||
|
||||
Common::StringList PAKSaveManager::listSavefiles(const Common::String &pattern) {
|
||||
PAKDIR *dirp = pakfs_opendir();
|
||||
pakfs_dirent *dp;
|
||||
Common::StringList list;
|
||||
|
||||
while ((dp = pakfs_readdir(dirp)) != NULL) {
|
||||
if (matches(pattern.c_str(), dp->entryname))
|
||||
list.push_back(dp->entryname);
|
||||
|
||||
free(dp);
|
||||
}
|
||||
|
||||
pakfs_closedir(dirp);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static bool matches(const char *glob, const char *name) {
|
||||
while (*glob)
|
||||
if (*glob == '*') {
|
||||
while (*glob == '*')
|
||||
glob++;
|
||||
do {
|
||||
if ((*name == *glob || *glob == '?') &&
|
||||
matches(glob, name))
|
||||
return true;
|
||||
} while (*name++);
|
||||
return false;
|
||||
} else if (!*name)
|
||||
return false;
|
||||
else if (*glob == '?' || *glob == *name) {
|
||||
glob++;
|
||||
name++;
|
||||
} else
|
||||
return false;
|
||||
return !*name;
|
||||
}
|
||||
|
124
backends/platform/n64/pakfs_save_manager.h
Normal file
124
backends/platform/n64/pakfs_save_manager.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PAKFS_SAVE_MANAGER__
|
||||
#define __PAKFS_SAVE_MANAGER__
|
||||
|
||||
#include <common/savefile.h>
|
||||
#include <common/zlib.h>
|
||||
|
||||
#include <pakfs.h> // N64 PakFS library
|
||||
|
||||
bool deleteSaveGame(const char *filename);
|
||||
|
||||
class InPAKSave : public Common::InSaveFile {
|
||||
private:
|
||||
PAKFILE *fd;
|
||||
|
||||
uint32 read(void *buf, uint32 cnt);
|
||||
bool skip(uint32 offset);
|
||||
bool seek(int32 offs, int whence);
|
||||
|
||||
public:
|
||||
InPAKSave() : fd(0) { }
|
||||
|
||||
~InPAKSave() {
|
||||
if (fd != NULL)
|
||||
pakfs_close(fd);
|
||||
}
|
||||
|
||||
bool eos() const {
|
||||
return pakfs_eof(fd);
|
||||
}
|
||||
void clearErr() {
|
||||
pakfs_clearerr(fd);
|
||||
}
|
||||
int32 pos() const {
|
||||
return pakfs_tell(fd);
|
||||
}
|
||||
int32 size() const {
|
||||
return fd->size;
|
||||
}
|
||||
|
||||
bool readSaveGame(const char *filename) {
|
||||
fd = pakfs_open(filename, "r");
|
||||
return (fd != NULL);
|
||||
}
|
||||
};
|
||||
|
||||
class OutPAKSave : public Common::OutSaveFile {
|
||||
private:
|
||||
PAKFILE *fd;
|
||||
|
||||
public:
|
||||
uint32 write(const void *buf, uint32 cnt);
|
||||
|
||||
OutPAKSave(const char *_filename) {
|
||||
fd = pakfs_open(_filename, "w");
|
||||
}
|
||||
|
||||
~OutPAKSave() {
|
||||
if (fd != NULL) {
|
||||
finalize();
|
||||
pakfs_close(fd);
|
||||
flushCurrentPakData();
|
||||
}
|
||||
}
|
||||
|
||||
bool err() const {
|
||||
return pakfs_error(fd);
|
||||
}
|
||||
void clearErr() {
|
||||
pakfs_clearerr(fd);
|
||||
}
|
||||
void finalize() {
|
||||
pakfs_flush(fd);
|
||||
}
|
||||
};
|
||||
|
||||
class PAKSaveManager : public Common::SaveFileManager {
|
||||
public:
|
||||
|
||||
virtual Common::OutSaveFile *openForSaving(const Common::String &filename) {
|
||||
return Common::wrapCompressedWriteStream(new OutPAKSave(filename.c_str()));
|
||||
}
|
||||
|
||||
virtual Common::InSaveFile *openForLoading(const Common::String &filename) {
|
||||
InPAKSave *s = new InPAKSave();
|
||||
if (s->readSaveGame(filename.c_str())) {
|
||||
return Common::wrapCompressedReadStream(s);
|
||||
} else {
|
||||
delete s;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool removeSavefile(const Common::String &filename) {
|
||||
return ::deleteSaveGame(filename.c_str());
|
||||
}
|
||||
|
||||
virtual Common::StringList listSavefiles(const Common::String &pattern);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
46
backends/platform/n64/portdefs.h
Normal file
46
backends/platform/n64/portdefs.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __N64_PORTDEFS__
|
||||
#define __N64_PORTDEFS__
|
||||
|
||||
#include <n64utils.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#undef assert
|
||||
#define assert(x) ((x) ? 0 : (print_error("["#x"] (%s:%d)", __FILE__, __LINE__)))
|
||||
|
||||
#endif
|
||||
|
|
@ -45,6 +45,13 @@
|
|||
#define fflush(file) DS::std_fflush(file)
|
||||
#endif
|
||||
|
||||
#ifdef __N64__
|
||||
#include <n64utils.h>
|
||||
|
||||
#define fputs(str, file) asm("nop");
|
||||
#define fflush(a) asm("nop");
|
||||
#define OutputDebugString addLineTextLayer
|
||||
#endif
|
||||
|
||||
|
||||
// TODO: Move gDebugLevel into namespace Common.
|
||||
|
|
|
@ -301,6 +301,31 @@
|
|||
#define SCUMM_LITTLE_ENDIAN
|
||||
#define SCUMM_NEED_ALIGNMENT
|
||||
|
||||
#elif defined(__N64__)
|
||||
|
||||
#define scumm_stricmp strcasecmp
|
||||
#define scumm_strnicmp strncasecmp
|
||||
|
||||
#define SCUMM_BIG_ENDIAN
|
||||
#define SCUMM_NEED_ALIGNMENT
|
||||
|
||||
#define STRINGBUFLEN 256
|
||||
|
||||
#define SCUMMVM_DONT_DEFINE_TYPES
|
||||
typedef unsigned char byte;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short int uint16;
|
||||
typedef signed short int int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
|
||||
#elif defined(__PSP__)
|
||||
|
||||
#include <malloc.h>
|
||||
|
|
|
@ -46,6 +46,9 @@ extern bool isSmartphone();
|
|||
#define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file)
|
||||
#endif
|
||||
|
||||
#ifdef __N64__
|
||||
#define fputs(str, file) asm("nop");
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) {
|
|||
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
|
||||
saveSaveGameHeader(out, hdr);
|
||||
}
|
||||
#if !defined(__DS__) /* && !defined(__PLAYSTATION2__) */
|
||||
#if !defined(__DS__) && !defined(__N64__) /* && !defined(__PLAYSTATION2__) */
|
||||
Graphics::saveThumbnail(*out);
|
||||
#endif
|
||||
saveInfos(out);
|
||||
|
|
|
@ -117,10 +117,17 @@ struct ColorMasks<555> {
|
|||
kGreenBits = 5,
|
||||
kBlueBits = 5,
|
||||
|
||||
#ifdef __N64__
|
||||
kAlphaShift = 0,
|
||||
kRedShift = kBlueBits+kGreenBits+1,
|
||||
kGreenShift = kBlueBits + 1,
|
||||
kBlueShift = 1,
|
||||
#else
|
||||
kAlphaShift = 0,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
#endif
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "mame.h"
|
||||
|
||||
#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__)
|
||||
#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__)
|
||||
#include "common/config-manager.h"
|
||||
#endif
|
||||
|
||||
|
@ -1212,7 +1212,7 @@ FM_OPL *makeAdlibOPL(int rate) {
|
|||
// We need to emulate one YM3812 chip
|
||||
int env_bits = FMOPL_ENV_BITS_HQ;
|
||||
int eg_ent = FMOPL_EG_ENT_HQ;
|
||||
#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__)
|
||||
#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__)
|
||||
if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
|
||||
env_bits = FMOPL_ENV_BITS_HQ;
|
||||
eg_ent = FMOPL_EG_ENT_HQ;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue