diff options
| author | Stephen Kennedy | 2008-07-22 00:15:13 +0000 | 
|---|---|---|
| committer | Stephen Kennedy | 2008-07-22 00:15:13 +0000 | 
| commit | 0861fa4c00f0ecb82f3607127c8278d55f95376c (patch) | |
| tree | d757c116b163a401f00859503a7db755b6627504 /backends/platform | |
| parent | a58080bd58bbcc9f7c710fade55620049bae14e4 (diff) | |
| parent | e09eb75ef77d6e76b763b3a47540a530013a887f (diff) | |
| download | scummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.tar.gz scummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.tar.bz2 scummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.zip | |
Merged revisions 32879,32883,32895,32899,32902-32904,32910-32912,32923-32924,32930-32931,32938,32940,32948-32949,32951,32960-32964,32966-32970,32972-32974,32976,32978,32983,32986-32990,32992,32994,33002-33004,33006-33007,33009-33010,33014,33017,33021-33023,33030,33033,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: r33185
Diffstat (limited to 'backends/platform')
28 files changed, 3527 insertions, 539 deletions
| diff --git a/backends/platform/dc/Makefile b/backends/platform/dc/Makefile index 5c01b20b27..db5861903b 100644 --- a/backends/platform/dc/Makefile +++ b/backends/platform/dc/Makefile @@ -33,8 +33,33 @@ ifdef DYNAMIC_MODULES  DEFINES += -DDYNAMIC_MODULES  PRE_OBJS_FLAGS = -Wl,--whole-archive  POST_OBJS_FLAGS = -Wl,--no-whole-archive +ENABLED=DYNAMIC_PLUGIN +else +ENABLED=STATIC_PLUGIN  endif +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) +ENABLE_HE = $(ENABLED) +ENABLE_AGI = $(ENABLED) +ENABLE_AGOS = $(ENABLED) +ENABLE_CINE = $(ENABLED) +ENABLE_CRUISE = $(ENABLED) +ENABLE_DRASCULA = $(ENABLED) +ENABLE_GOB = $(ENABLED) +ENABLE_IGOR = $(ENABLED) +ENABLE_KYRA = $(ENABLED) +ENABLE_LURE = $(ENABLED) +ENABLE_M4 = $(ENABLED) +ENABLE_MADE = $(ENABLED) +ENABLE_PARALLACTION = $(ENABLED) +ENABLE_QUEEN = $(ENABLED) +ENABLE_SAGA = $(ENABLED) +ENABLE_SKY = $(ENABLED) +ENABLE_SWORD1 = $(ENABLED) +ENABLE_SWORD2 = $(ENABLED) +ENABLE_TOUCHE = $(ENABLED) +  OBJS :=	dcmain.o time.o display.o audio.o input.o selector.o icon.o \  	label.o vmsave.o softkbd.o dcloader.o cache.o dc-fs.o @@ -50,7 +75,7 @@ SCUMMVM.BIN : scummvm.bin  plugin_dist :  	for p in plugins/*.plg; do \ -	  sh-elf-strip -g -o "`basename \"$$p\" | tr '[:lower:]' '[:upper:]'`" "$$p"; \ +	  sh-elf-strip -g -o "`basename \"$$p\" | LC_CTYPE=C tr '[:lower:]' '[:upper:]'`" "$$p"; \  	done  dist : SCUMMVM.BIN plugins plugin_dist diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index a130509e36..f4706807f7 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -168,7 +168,7 @@ bool displayModeIs8Bit = false;  u8 gameID;  bool snapToBorder = false; -bool consoleEnable = false; +bool consoleEnable = true;  bool gameScreenSwap = false;  bool isCpuScalerEnabled();  //#define HEAVY_LOGGING @@ -899,12 +899,6 @@ u16* get8BitBackBuffer() {  		return BG_GFX + 0x10000;		// 16bit qty!  } -void setSoundProc(OSystem_DS::SoundProc proc, void* param) { -//	consolePrintf("Set sound callback"); -	soundCallback = proc; -	soundParam = param; -} -  // The sound system in ScummVM seems to always return stereo interleaved samples.  // Here, I'm treating an 11Khz stereo stream as a 22Khz mono stream, which works sorta ok, but is  // a horrible bodge.  Any advice on how to change the engine to output mono would be greatly @@ -914,7 +908,8 @@ void doSoundCallback() {  	consolePrintf("doSoundCallback...");  	#endif -	if (soundCallback) { +	if (OSystem_DS::instance()) +	if (OSystem_DS::instance()->getMixerImpl()) {  		lastCallbackFrame = frameCount;  		for (int r = IPC->playingSection; r < IPC->playingSection + 4; r++) { @@ -923,7 +918,7 @@ void doSoundCallback() {  			if (IPC->fillNeeded[chunk]) {  				IPC->fillNeeded[chunk] = false;  				DC_FlushAll(); -				soundCallback(soundParam, (byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1); +				OSystem_DS::instance()->getMixerImpl()->mixCallback((byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);  				IPC->fillNeeded[chunk] = false;  				DC_FlushAll();  			} diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h index f20442b11e..43258b5c5d 100644 --- a/backends/platform/ds/arm9/source/dsmain.h +++ b/backends/platform/ds/arm9/source/dsmain.h @@ -88,7 +88,6 @@ int 	getMillis();													// Return the current runtime in milliseconds  void 	doTimerCallback();												// Call callback function if required  // Sound -void 	setSoundProc(OSystem_DS::SoundProc proc, void* param);			// Setup a callback function for sound  void 	doSoundCallback();												// Call function if sound buffers need more data  void 	playSound(const void* data, u32 length, bool loop, bool adpcm = false, int rate = 22050);		// Start a sound  void 	stopSound(int channel); diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp index d2c3b579bd..79b0c5390b 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.cpp +++ b/backends/platform/ds/arm9/source/osystem_ds.cpp @@ -67,10 +67,12 @@ void OSystem_DS::initBackend() {  	ConfMan.setInt("autosave_period", 0);  	ConfMan.setBool("FM_medium_quality", true); -	_mixer = new DSAudioMixer; -	_timer = new DSTimerManager; -	DS::setSoundProc(Audio::Mixer::mixCallback, _mixer); -    DS::setTimerCallback(&OSystem_DS::timerHandler, 10); +	_mixer = new DSAudioMixer(this); +	_timer = new DSTimerManager(); +    	DS::setTimerCallback(&OSystem_DS::timerHandler, 10); + +	_mixer->setOutputRate(11025 /*DS::getSoundFrequency()*/); +	_mixer->setReady(true);  	OSystem::initBackend();  } @@ -139,7 +141,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {  		green >>= 3;  		blue >>= 3; -//		if (r != 255) +		if (r != 255)  		{		  			BG_PALETTE[r] = red | (green << 5) | (blue << 10);  			if (!DS::getKeyboardEnable()) { @@ -158,13 +160,13 @@ bool OSystem_DS::grabRawScreen(Graphics::Surface* surf) {  	// Ensure we copy using 16 bit quantities due to limitation of VRAM addressing -	u16* image = (u16 *) DS::get8BitBackBuffer(); +	const u16* image = (const u16 *) DS::get8BitBackBuffer();  	for (int y = 0; y <  DS::getGameHeight(); y++)  	{  		DC_FlushRange(image + (y << 8), DS::getGameWidth());  		for (int x = 0; x < DS::getGameWidth() >> 1; x++)  		{ -			*(((u16 *) (surf->pixels)) + y * (DS::getGameWidth() >> 1) + x) = image[y << 8 + x]; +			*(((u16 *) (surf->pixels)) + y * (DS::getGameWidth() >> 1) + x) = image[(y << 8) + x];  		}  	} @@ -277,7 +279,7 @@ void OSystem_DS::grabOverlay (OverlayColor *buf, int pitch) {  void OSystem_DS::copyRectToOverlay (const OverlayColor *buf, int pitch, int x, int y, int w, int h) {  	u16* bg = (u16 *) DS::get16BitBackBuffer(); -	u16* src = (u16 *) buf; +	const u16* src = (const u16 *) buf;  //	if (x + w > 256) w = 256 - x;  	//if (x + h > 256) h = 256 - y; diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h index e53575a4a5..8c8d661ad8 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.h +++ b/backends/platform/ds/arm9/source/osystem_ds.h @@ -30,10 +30,13 @@  #include "gbampsave.h"  #include "backends/saves/default/default-saves.h"  #include "backends/timer/default/default-timer.h" -#include "sound/mixer.h" +#include "sound/mixer_intern.h"  #include "graphics/surface.h" -class DSAudioMixer : public Audio::Mixer {	 +class DSAudioMixer : public Audio::MixerImpl {	 + +public: +	DSAudioMixer(OSystem* system) : Audio::MixerImpl(system) { }  };  class DSTimerManager : public DefaultTimerManager {	 @@ -62,7 +65,7 @@ protected:  	Graphics::Surface* createTempFrameBuffer();  public: -	typedef void (*SoundProc)(void *param, byte *buf, int len); +	typedef void (*SoundProc)(byte *buf, int len);  	typedef int  (*TimerProc)(int interval);  	OSystem_DS(); @@ -146,6 +149,8 @@ public:  	virtual void unlockScreen();  	virtual Audio::Mixer* getMixer() { return _mixer; } +	Audio::MixerImpl* getMixerImpl() { return _mixer; } +  	virtual Common::TimerManager* getTimerManager() { return _timer; }  	static int timerHandler(int t); diff --git a/backends/platform/ds/arm9/source/wordcompletion.cpp b/backends/platform/ds/arm9/source/wordcompletion.cpp index 9eeeb62410..ff52572a40 100644 --- a/backends/platform/ds/arm9/source/wordcompletion.cpp +++ b/backends/platform/ds/arm9/source/wordcompletion.cpp @@ -1,6 +1,6 @@  #include "wordcompletion.h" -#include "engines/agi/agi.h"  #include "osystem_ds.h" +#include "engines/agi/agi.h"	// Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h  #ifdef ENABLE_AGI diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 22cd4eaa1b..204f4f7a16 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -19,16 +19,17 @@ RM 	= rm -f  srcdir = ../../..  VPATH = $(srcdir)  INCDIR = ../../../ +DEPDIR = .deps  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 = /home/robby/libStuffNew/ps2sdk-ports +PS2SDK_PORTS = /mnt/winxp/scummvm/ports  PS2SDK_PORTS_INCS = /ucl /zlib/include /libmad/ee/include  PS2SDK_PORTS_LIBS = /ucl /zlib/lib /libmad/ee/lib  # 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_LIBS = /SjPcm/ee/lib /mpeg2dec/libmpeg2 /tremor/tremor diff --git a/backends/platform/ps2/fileio.cpp b/backends/platform/ps2/fileio.cpp index bc310a43f4..b7fa8d03f1 100644 --- a/backends/platform/ps2/fileio.cpp +++ b/backends/platform/ps2/fileio.cpp @@ -340,8 +340,6 @@ FILE *ps2_fopen(const char *fname, const char *mode) {  		assert(cacheListSema >= 0);  	} -	//printf("ps2_fopen: %s, %s\n", fname, mode); -  	if (((mode[0] != 'r') && (mode[0] != 'w')) || ((mode[1] != '\0') && (mode[1] != 'b'))) {  		printf("unsupported mode \"%s\" for file \"%s\"\n", mode, fname);  		return NULL; @@ -363,6 +361,8 @@ FILE *ps2_fopen(const char *fname, const char *mode) {  	} else {  		// Regular access to one of the devices +		printf("ps2_fopen = %s\n", fname); // romeo : temp +  		if (!rdOnly)  			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; -		if (rdOnly && tocManager.haveEntries()) +		if (tocManager.haveEntries())  			cacheId = tocManager.fileExists(fname);  		if (cacheId != 0) {  			Ps2File *file = findInCache(cacheId); -			if (file) +			if (file) { +				printf("  findInCache(%x)\n", cacheId); // romeo : temp  				return (FILE*)file; +			}  			bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun");  			file = new Ps2ReadFile(cacheId, isAudioFile);  			if (file->open(fname)) {  				openFileCount++; +				printf("  new cacheID = %x\n", cacheId); // romeo : temp  				return (FILE*)file;  			} else  				delete file; @@ -579,7 +582,7 @@ void TocManager::readEntries(const char *root) {  	}  	char readPath[256];  	sprintf(readPath, "%s/", _root); -	printf("readDir: %s\n", readPath); +	printf("readDir: %s    (root: %s )\n", readPath, root);  	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  		iox_dirent_t dirent;  		int fd = fio.dopen(path); +		TocNode *eNode = NULL; // = *node; // entry node +		bool first = true; + +		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 '.' and '..' +			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);  					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; -						char nextPath[256]; -						sprintf(nextPath, "%s%s/", path, dirent.name); -						readDir(nextPath, &((*node)->sub), level + 1); -					} else +						printf("dirent.name = %s [DIR]\n", dirent.name); +					} +					else {  						(*node)->isDir = false; +						printf("dirent.name = %s\n", dirent.name); +					} +  					node = &((*node)->next);  				} +			} +  			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) { diff --git a/backends/platform/ps2/iop/rpckbd/Makefile b/backends/platform/ps2/iop/rpckbd/Makefile new file mode 100644 index 0000000000..b25efa3660 --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/Makefile @@ -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 diff --git a/backends/platform/ps2/iop/rpckbd/include/ps2kbd.h b/backends/platform/ps2/iop/rpckbd/include/ps2kbd.h new file mode 100644 index 0000000000..f16c7ca12b --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/include/ps2kbd.h @@ -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 diff --git a/backends/platform/ps2/iop/rpckbd/src/imports.lst b/backends/platform/ps2/iop/rpckbd/src/imports.lst new file mode 100644 index 0000000000..41e13e6e73 --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/src/imports.lst @@ -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 + diff --git a/backends/platform/ps2/iop/rpckbd/src/irx_imports.h b/backends/platform/ps2/iop/rpckbd/src/irx_imports.h new file mode 100644 index 0000000000..6ecc8e5864 --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/src/irx_imports.h @@ -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 */ diff --git a/backends/platform/ps2/iop/rpckbd/src/ps2kbd.c b/backends/platform/ps2/iop/rpckbd/src/ps2kbd.c new file mode 100644 index 0000000000..f87a47f0cb --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/src/ps2kbd.c @@ -0,0 +1,1199 @@ +/* +# _____     ___ ____     ___ ____ +#  ____|   |    ____|   |        | |____| +# |     ___|   |____ ___|    ____| |    \    PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2005, 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 +*/ + +#include "types.h" +#include "ioman.h" +#include "loadcore.h" +#include "stdio.h" +#include "sifcmd.h" +#include "sifrpc.h" +#include "sysclib.h" +#include "sysmem.h" +#include "usbd.h" +#include "usbd_macro.h" +#include "thbase.h" +#include "thevent.h" +#include "thsemap.h" + +#include "ps2kbd.h" +#include "us_keymap.h" + +#define PS2KBD_VERSION 0x100 + +#define USB_SUBCLASS_BOOT 1 +#define USB_HIDPROTO_KEYBOARD 1 + +#define PS2KBD_MAXDEV 2 +#define PS2KBD_MAXKEYS 6 + +#define PS2KBD_DEFLINELEN 4096 +#define PS2KBD_DEFREPEATRATE 100 +/* Default repeat rate in milliseconds */ +#define PS2KBD_REPEATWAIT 1000 +/* Number of milliseconds to wait before starting key repeat */ +#define USB_KEYB_NUMLOCK 0x53 +#define USB_KEYB_CAPSLOCK 0x39 +#define USB_KEYB_SCRLOCK 0x47 + +#define USB_KEYB_NUMPAD_START 0x54 +#define USB_KEYB_NUMPAD_END 0x63 + +#define SEMA_ZERO -419 +#define SEMA_DELETED -425 + +int ps2kbd_init(); +void ps2kbd_config_set(int resultCode, int bytes, void *arg); +void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg); +void ps2kbd_data_recv(int resultCode, int bytes, void *arg); +int ps2kbd_probe(int devId); +int ps2kbd_connect(int devId); +int ps2kbd_disconnect(int devId); +void usb_getstring(int endp, int index, char *desc); + +typedef struct _kbd_data_recv + +{ +  u8 mod_keys; +  u8 reserved; +  u8 keycodes[PS2KBD_MAXKEYS]; +} kbd_data_recv; + +typedef struct _keyb_dev + +{ +  int configEndp; +  int dataEndp; +  int packetSize; +  int devId; +  int interfaceNo;    /* Holds the interface number selected on this device */ +  char repeatkeys[2]; +  u32 eventmask; +  u8 ledStatus;     /* Maintains state on the led status */ +  kbd_data_recv oldData; +  kbd_data_recv data; /* Holds the data for the transfers */ +} kbd_dev; + +/* Global Variables */ + +int kbd_readmode; +u32 kbd_repeatrate; +kbd_dev *devices[PS2KBD_MAXDEV]; /* Holds a list of current devices */ +int dev_count; +UsbDriver kbd_driver = { NULL, NULL, "PS2Kbd", ps2kbd_probe, ps2kbd_connect, ps2kbd_disconnect }; +u8 *lineBuffer; +u32 lineStartP, lineEndP; +int lineSema; +int bufferSema; +u32 lineSize; +u8 keymap[PS2KBD_KEYMAP_SIZE];         /* Normal key map */ +u8 shiftkeymap[PS2KBD_KEYMAP_SIZE];  /* Shifted key map */ +u8 keycap[PS2KBD_KEYMAP_SIZE];          /* Does this key get shifted by capslock ? */ +u8 special_keys[PS2KBD_KEYMAP_SIZE]; +u8 control_map[PS2KBD_KEYMAP_SIZE]; +u8 alt_map[PS2KBD_KEYMAP_SIZE]; +//static struct fileio_driver kbd_fdriver; +iop_device_t kbd_filedrv; +u8 keyModValue[8] = { 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 }; +int repeat_tid; +int eventid;   /* Id of the repeat event */ + +int _start () +{ +  FlushDcache(); + +  ps2kbd_init(); + +  printf("PS2KBD - USB Keyboard Library\n"); + +  return 0; + +} + +int ps2kbd_probe(int devId) + +{ +  UsbDeviceDescriptor *dev; +  UsbConfigDescriptor *conf; +  UsbInterfaceDescriptor *intf; +  UsbEndpointDescriptor *endp; +  //UsbStringDescriptor *str; + +  if(dev_count >= PS2KBD_MAXDEV) +    { +      printf("ERROR: Maximum keyboard devices reached\n"); +      return 0; +    } + +  //printf("PS2Kbd_probe devId %d\n", devId); + +  dev = UsbGetDeviceStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */ +  if(!dev)  +    { +      printf("ERROR: Couldn't get device descriptor\n"); +      return 0; +    } + +  //printf("Device class %d, Size %d, Man %d, Product %d Cpnfigurations %d\n", dev->bDeviceClass, dev->bMaxPacketSize0, dev->iManufacturer, dev->iProduct, dev->bNumConfigurations); +  /* Check that the device class is specified in the interfaces and it has at least one configuration */ +  if((dev->bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->bNumConfigurations < 1)) +    { +      //printf("This is not the droid you're looking for\n"); +      return 0; +    } + +  conf = UsbGetDeviceStaticDescriptor(devId, dev, USB_DT_CONFIG); +  if(!conf) +    { +      printf("ERROR: Couldn't get configuration descriptor\n"); +      return 0; +    } +  //printf("Config Length %d Total %d Interfaces %d\n", conf->bLength, conf->wTotalLength, conf->bNumInterfaces); + +  if((conf->bNumInterfaces < 1) || (conf->wTotalLength < (sizeof(UsbConfigDescriptor) + sizeof(UsbInterfaceDescriptor)))) +    { +      printf("ERROR: No interfaces available\n"); +      return 0; +    } +      +  intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */ +/*   printf("Interface Length %d Endpoints %d Class %d Sub %d Proto %d\n", intf->bLength, */ +/* 	 intf->bNumEndpoints, intf->bInterfaceClass, intf->bInterfaceSubClass, */ +/* 	 intf->bInterfaceProtocol); */ + +  if((intf->bInterfaceClass != USB_CLASS_HID) || (intf->bInterfaceSubClass != USB_SUBCLASS_BOOT) || +     (intf->bInterfaceProtocol != USB_HIDPROTO_KEYBOARD) || (intf->bNumEndpoints < 1)) + +    { +      //printf("We came, we saw, we told it to fuck off\n"); +      return 0; +    } + +  endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength); +  endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */ + +  //printf("Endpoint 1 Addr %d, Attr %d, MaxPacket %d\n", endp->bEndpointAddress, endp->bmAttributes, endp->wMaxPacketSizeLB); +   +  if(((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) || +     ((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)) +    { +      printf("ERROR: Endpoint not interrupt type and/or an input\n"); +      return 0; +    } + +  printf("PS2KBD: Found a keyboard device\n"); + +  return 1; +} + +int ps2kbd_connect(int devId) + +{ +  /* Assume we can only get here if we have already checked the device is kosher */ + +  UsbDeviceDescriptor *dev; +  UsbConfigDescriptor *conf; +  UsbInterfaceDescriptor *intf; +  UsbEndpointDescriptor *endp; +  kbd_dev *currDev; +  int devLoop; + +  //printf("PS2Kbd_connect devId %d\n", devId); + +  dev = UsbGetDeviceStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */ +  if(!dev)  +    { +      printf("ERROR: Couldn't get device descriptor\n"); +      return 1; +    } + +  conf = UsbGetDeviceStaticDescriptor(devId, dev, USB_DT_CONFIG); +  if(!conf) +    { +      printf("ERROR: Couldn't get configuration descriptor\n"); +      return 1; +    } +      +  intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */ +  endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength); +  endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */ + +  for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) +    { +      if(devices[devLoop] == NULL) +	{ +	  break; +	} +    } + +  if(devLoop == PS2KBD_MAXDEV) +    { +      /* How the f*** did we end up here ??? */ +      printf("ERROR: Device Weirdness!!\n"); +      return 1; +    } + +  currDev = (kbd_dev *) AllocSysMemory(0, sizeof(kbd_dev), NULL); +  if(!currDev) +    { +      printf("ERROR: Couldn't allocate a device point for the kbd\n"); +      return 1; +    } + +  devices[devLoop] = currDev; +  memset(currDev, 0, sizeof(kbd_dev)); +  currDev->configEndp = UsbOpenEndpoint(devId, NULL); +  currDev->dataEndp = UsbOpenEndpoint(devId, endp); +  currDev->packetSize = endp->wMaxPacketSizeLB | ((int) endp->wMaxPacketSizeHB << 8); +  currDev->eventmask = (1 << devLoop); +  if(currDev->packetSize > sizeof(kbd_data_recv)) +    { +      currDev->packetSize = sizeof(kbd_data_recv); +    } + +  if(dev->iManufacturer != 0) +    { +      usb_getstring(currDev->configEndp, dev->iManufacturer, "Keyboard Manufacturer"); +    } + +  if(dev->iProduct != 0) +    { +      usb_getstring(currDev->configEndp, dev->iProduct, "Keyboard Product"); +    } + +  currDev->devId = devId; +  currDev->interfaceNo = intf->bInterfaceNumber; +  currDev->ledStatus = 0; + +  UsbSetDevicePrivateData(devId, currDev); /* Set the index for the device data */ + +  //printf("Configuration value %d\n", conf->bConfigurationValue); +  UsbSetDeviceConfiguration(currDev->configEndp, conf->bConfigurationValue, ps2kbd_config_set, currDev); + +  dev_count++; /* Increment device count */ +  printf("PS2KBD: Connected device\n"); + +  return 0; +} + +int ps2kbd_disconnect(int devId) + +{ +  int devLoop; +  printf("PS2Kbd_disconnect devId %d\n", devId); + +  for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) +    { +      if((devices[devLoop]) && (devices[devLoop]->devId == devId)) +	{ +	  dev_count--; +	  FreeSysMemory(devices[devLoop]); +	  devices[devLoop] = NULL; +	  printf("PS2KBD: Disconnected device\n"); +	  break; +	} +    } + +  return 0; +} + +typedef struct _string_descriptor + +{ +  u8 buf[200]; +  char *desc; +} string_descriptor;  + +void ps2kbd_getstring_set(int resultCode, int bytes, void *arg) + +{ +  UsbStringDescriptor *str = (UsbStringDescriptor *) arg; +  string_descriptor *strBuf = (string_descriptor *) arg; +  char string[50]; +  int strLoop; + +/*   printf("=========getstring=========\n"); */ + +/*   printf("PS2KEYBOARD: GET_DESCRIPTOR res %d, bytes %d, arg %p\n", resultCode, bytes, arg); */ + +  if(resultCode == USB_RC_OK) +    { +      memset(string, 0, 50); +      for(strLoop = 0; strLoop < ((bytes - 2) / 2); strLoop++) +	{ +	  string[strLoop] = str->wData[strLoop] & 0xFF; +	} +      printf("%s: %s\n", strBuf->desc, string); +    } +   +  FreeSysMemory(arg); +} + +void usb_getstring(int endp, int index, char *desc) + +{ +  u8 *data; +  string_descriptor *str; +  int ret;  + +  data = (u8 *) AllocSysMemory(0, sizeof(string_descriptor), NULL); +  str = (string_descriptor *) data; + +  if(data != NULL) +    { +      str->desc = desc; +      ret = UsbControlTransfer(endp, 0x80, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | index,  +			       0, sizeof(string_descriptor) - 4, data, ps2kbd_getstring_set, data); +      if(ret != USB_RC_OK) +	{ +	  printf("PS2KBD: Error sending string descriptor request\n"); +	  FreeSysMemory(data); +	} +    } +} + +void ps2kbd_config_set(int resultCode, int bytes, void *arg) +     /* Called when we have finished choosing our configuration */ + +{ +  kbd_dev *dev; + +  if(resultCode != USB_RC_OK) +    { +      printf("PS2KEYBOARD: Configuration set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg); +      return; +    } + +  //printf("PS2KEYBOARD: Configuration set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); +  /* Do a interrupt data transfer */ + +  dev = (kbd_dev *) arg; +  if(dev != NULL) +    { +      int ret; +       +      ret = UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_IDLE, 0, dev->interfaceNo, 0, NULL, ps2kbd_idlemode_set, arg); +    } +} + +void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg) + +{ +  kbd_dev *dev; + + + +  if(resultCode != USB_RC_OK) +    { +      printf("PS2KBD: Idlemode set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg); +      return; +    } +   +  dev = (kbd_dev *) arg; +  if(dev != NULL) +    { +      int ret; +       +      ret = UsbInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg); +    } +} + +void ps2kbd_led_set(int resultCode, int bytes, void *arg) + +{ +  //printf("LED Set\n"); +} + +void ps2kbd_build_uniquekeys(u8 *res, const u8 *new, const u8 *old) + +     /* Builds a list of unique keys */ + +{ +  int loopNew, loopOld; +  int loopRes = 0; +  int foundKey; + +  for(loopNew = 0; loopNew < PS2KBD_MAXKEYS; loopNew++) +    { +      if(new[loopNew] != 0) +	{ +	  foundKey = 0; +	  for(loopOld = 0; loopOld < PS2KBD_MAXKEYS; loopOld++) +	    { +	      if(new[loopNew] == old[loopOld]) +		{ +		  foundKey = 1; +		  break; +		} +	    } +	  if(!foundKey) +	    { +	      res[loopRes++] = new[loopNew]; +	    } +	} +    } +} + +u32 ps2kbd_repeathandler(void *arg) + +{ +  kbd_dev *dev = arg; +  iop_sys_clock_t t; +  //printf("Repeat handler\n"); + +  iSetEventFlag(eventid, dev->eventmask); + +  USec2SysClock(kbd_repeatrate * 1000, &t); +  iSetAlarm(&t, ps2kbd_repeathandler, arg); + +  return t.hi; +} + +void ps2kbd_getkeys(u8 keyMods, u8 ledStatus, const u8 *keys, kbd_dev *dev) + +{ +  int loopKey; +  int tempPos = 0; +  int byteCount = 0; +  u8 currChars[2]; + +  if(lineStartP < lineEndP) +    { +      tempPos = lineStartP + lineSize; +    } +  else +    { +      tempPos = lineStartP; +    } +   +  for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) +    { +      u8 currKey = keys[loopKey]; + +      currChars[0] = 0; +      currChars[1] = 0; + +      if(lineEndP == (tempPos - 1)) +	{ +	  break; +	} + +      if(currKey) /* If this is a valid key */ +	{ +	  if((currKey >= USB_KEYB_NUMPAD_START) && (currKey <= USB_KEYB_NUMPAD_END)) +	    /* Handle numpad specially */ +	    { +	      if(ledStatus & PS2KBD_LED_NUMLOCK) +		{ +		  if(keymap[currKey]) +		    { +		      currChars[0] = keymap[currKey]; +		    } +		} +	      else +		{ +		  if(special_keys[currKey]) +		    { +		      currChars[0] = PS2KBD_ESCAPE_KEY; +		      currChars[1] = special_keys[currKey]; +		    } +		  else if(keymap[currKey] != '5') /* Make sure this isnt a 5 key :) */ +		    { +		      currChars[0] = keymap[currKey]; +		    } +		} +	    } +	  else if(special_keys[currKey]) /* This is a special key */ +	    { +	      currChars[0] = PS2KBD_ESCAPE_KEY; +	      currChars[1] = special_keys[currKey]; +	    } +	  else if(keyMods & PS2KBD_CTRL) /* CTRL */ +	    { +	      if(control_map[currKey]) +		{ +		  currChars[0] = control_map[currKey]; +		} +	    } +	  else if(keyMods & PS2KBD_ALT) /* ALT */ +	    { +	      if(alt_map[currKey]) +		{ +		  currChars[0] = alt_map[currKey]; +		} +	    } +	  else if(keyMods & PS2KBD_SHIFT) /* SHIFT */ +	    { +	      if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey])) +		{ +		  currChars[0] = keymap[currKey]; +		} +	      else +		{ +		  currChars[0] = shiftkeymap[currKey]; +		} +	    } +	  else /* Normal key */ +	    { +	      if(keymap[keys[loopKey]]) +		{ +		  if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey])) +		    { +		      currChars[0] = shiftkeymap[currKey]; +		    } +		  else +		    { +		      currChars[0] = keymap[currKey]; +		    } +		} +	    } +	} + +      if((currChars[0] == PS2KBD_ESCAPE_KEY) && (currChars[1] != 0)) +	{ +	  if(lineEndP != (tempPos - 2)) +	    { +	      lineBuffer[lineEndP++] = currChars[0]; +	      lineEndP %= lineSize; +	      lineBuffer[lineEndP++] = currChars[1]; +	      lineEndP %= lineSize; +	      byteCount += 2; +	    } +	  dev->repeatkeys[0] = currChars[0]; +	  dev->repeatkeys[1] = currChars[1]; +	} +      else if(currChars[0] != 0) +	{ +	  lineBuffer[lineEndP++] = currChars[0]; +	  lineEndP %= lineSize; +	  byteCount++; +	  dev->repeatkeys[0] = currChars[0]; +	  dev->repeatkeys[1] = 0; +	} +    } + +  if(byteCount > 0)  +    { +      iop_sys_clock_t t; +      /* Set alarm to do repeat rate */ +      //printf("repeatkeys %d %d\n", kbd_repeatkeys[0], kbd_repeatkeys[1]); +      USec2SysClock(PS2KBD_REPEATWAIT * 1000, &t); +      SetAlarm(&t, ps2kbd_repeathandler, dev); +    } + +  for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema to indicate data */ +    { +      SignalSema(bufferSema); +    } + +/*   lineBuffer[PS2KBD_DEFLINELEN - 1] = 0; */ +/*   printf(lineBuffer); */ +  //printf("lineStart %d, lineEnd %d\n", lineStartP, lineEndP); +} + + +void ps2kbd_getkeys_raw(u8 newKeyMods, u8 oldKeyMods, u8 *new, const u8 *old) + +{ +  int loopKey; +  u8 currKey; +  u8 keyMods = newKeyMods ^ oldKeyMods; +  u8 keyModsMap = newKeyMods & keyMods; +  int tempPos = 0; +  int byteCount = 0; + +  if(lineStartP < lineEndP) +    { +      tempPos = lineStartP + lineSize; +    } +  else +    { +      tempPos = lineStartP; +    } +   +  for(loopKey = 0; loopKey < 8; loopKey++) +    { +      int currMod = (1 << loopKey); +      if(keyMods & currMod)  +	{ +	  if(lineEndP == (tempPos - 2)) +	    { +	      return; +	    } + +	  currKey = keyModValue[loopKey]; + +	  if(keyModsMap & currMod) /* If key pressed */ +	    { +	      lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN; +	      //printf("Key down\n"); +	    } +	  else +	    { +	      lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP; +	      //printf("Key up\n"); +	    } + +	  lineEndP %= lineSize; +	  lineBuffer[lineEndP++] = currKey; +	  lineEndP %= lineSize; +	  byteCount += 2; +	  //printf("Key %d\n", currKey); +	} +    } + +  for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) +    { +      if(lineEndP == (tempPos - 2)) +	{ +	  return; +	} + +      if(new[loopKey] != 0) +	{ +	  lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN; +	  lineEndP %= lineSize; +	  lineBuffer[lineEndP++] = new[loopKey]; +	  lineEndP %= lineSize; +	  byteCount += 2; +	  //printf("Key down\nKey %d\n", new[loopKey]); +	} + +    } + +  for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) +    { +      if(lineEndP == (tempPos - 2)) +	{ +	  return; +	} + +      if(old[loopKey] != 0) +	{ +	  lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP; +	  lineEndP %= lineSize; +	  lineBuffer[lineEndP++] = old[loopKey]; +	  lineEndP %= lineSize; +	  byteCount += 2; +	  //printf("Key up\nKey %d\n", old[loopKey]); +	} + +    } + +  for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema for the number of bytes read */ +    { +      SignalSema(bufferSema); +    } +} + +void ps2kbd_data_recv(int resultCode, int bytes, void *arg) + +{ +  kbd_dev *dev; +  int ret; +  int phantom; +  int loop; + +  if(resultCode != USB_RC_OK) +    { +      printf("PS2KEYBOARD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); +      return; +    } +   +  //printf("PS2KBD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); + +  dev = (kbd_dev *) arg; +  if(dev == NULL) +    { +      printf("PS2KBD: dev == NULL\n"); +      return; +    } +     +/*       printf("PS2KBD Modifiers %02X, Keys ", dev->data.mod_keys); */ +/*       for(loop = 0; loop < PS2KBD_MAXKEYS; loop++) */ +/* 	{ */ +/* 	  printf("%02X ", dev->data.keycodes[loop]); */ +/* 	} */ +/*       printf("\n"); */ + +  CancelAlarm(ps2kbd_repeathandler, dev); /* Make sure repeat alarm is cancelled */ + +  /* Check for phantom states */ +  phantom = 1; +  for(loop = 0; loop < PS2KBD_MAXKEYS; loop++) +    { +      if(dev->data.keycodes[loop] != 1) +	{ +	  phantom = 0; +	  break; +	} +    } +   +  if(!phantom) /* If not in a phantom state */ +    { +      u8 uniqueKeys[PS2KBD_MAXKEYS]; +      u8 missingKeys[PS2KBD_MAXKEYS]; +      int loopKey; + +      memset(uniqueKeys, 0, PS2KBD_MAXKEYS); +      memset(missingKeys, 0, PS2KBD_MAXKEYS); +      ps2kbd_build_uniquekeys(uniqueKeys, dev->data.keycodes, dev->oldData.keycodes); +      ps2kbd_build_uniquekeys(missingKeys, dev->oldData.keycodes, dev->data.keycodes); +      /* Build new and missing key lists */ + +/*       printf("Unique keys : "); */ +/*       for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */ +/* 	{ */ +/* 	  printf("%02X ", uniqueKeys[loopKey]); */ +/* 	} */ +/*       printf("\n"); */ + +/*       printf("Missing keys : "); */ +/*       for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */ +/* 	{ */ +/* 	  printf("%02X ", missingKeys[loopKey]); */ +/* 	} */ +/*       printf("\n"); */ +       +      if(kbd_readmode == PS2KBD_READMODE_NORMAL) +	{ +	  u8 ledStatus; + +	  ledStatus = dev->ledStatus; +	  //printf("ledStatus %02X\n", ledStatus); +	   +	  for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) /* Process key codes */ +	    { +	      switch(uniqueKeys[loopKey]) +		{ +		case USB_KEYB_NUMLOCK :  +		  ledStatus ^= PS2KBD_LED_NUMLOCK; +		  uniqueKeys[loopKey] = 0; +		  break; +		case USB_KEYB_CAPSLOCK :  +		  ledStatus ^= PS2KBD_LED_CAPSLOCK; +		  uniqueKeys[loopKey] = 0; +		  break; +		case USB_KEYB_SCRLOCK : +		  ledStatus ^= PS2KBD_LED_SCRLOCK; +		  uniqueKeys[loopKey] = 0; +		  break; +		} +	    } +	   +	  if(ledStatus != dev->ledStatus) +	    { +	      dev->ledStatus = ledStatus & PS2KBD_LED_MASK; +	      //printf("LEDS %02X\n", dev->ledStatus); +	      /* Call Set LEDS */ +	      UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200,  +				 dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, arg); +	    } +	   +	  WaitSema(lineSema); /* Make sure no other thread is going to manipulate the buffer */ +	  ps2kbd_getkeys(dev->data.mod_keys, dev->ledStatus, uniqueKeys, dev); /* read in remaining keys */ +	  SignalSema(lineSema); +	} +      else /* RAW Mode */ +	{ +	  WaitSema(lineSema); +	  ps2kbd_getkeys_raw(dev->data.mod_keys, dev->oldData.mod_keys, uniqueKeys, missingKeys); +	  SignalSema(lineSema); +	} + +      memcpy(&dev->oldData, &dev->data, sizeof(kbd_data_recv)); +    } +   +  ret = UsbInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg); +} + +void flushbuffer() + +{ +  iop_sema_t s; + +  lineStartP = 0; +  lineEndP = 0; +  memset(lineBuffer, 0, lineSize); +   +  DeleteSema(bufferSema); +  s.initial = 0; +  s.max = lineSize; +  s.option = 0; +  s.attr = 0; +  bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */ +   +  if(bufferSema <= 0) +    { +      printf("Error creating buffer sema\n"); +    } +} + +void ps2kbd_rpc_setreadmode(u32 readmode) + +{ +  int devLoop; + +  if(readmode == kbd_readmode) return;  + +  if((readmode == PS2KBD_READMODE_NORMAL) || (readmode == PS2KBD_READMODE_RAW)) +    { +      /* Reset line buffer */ +      //printf("ioctl_setreadmode %d\n", readmode); +      for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) +	{ +	  CancelAlarm(ps2kbd_repeathandler, devices[devLoop]); +	} + +      WaitSema(lineSema); +      kbd_readmode = readmode; +      flushbuffer(); +      SignalSema(lineSema); +    } +} + +void ps2kbd_rpc_setkeymap(kbd_keymap *keymaps) + +{ +  //printf("ioctl_setkeymap %p\n", keymaps); +  WaitSema(lineSema);   /* Lock the input so you dont end up with weird results */ +  memcpy(keymap, keymaps->keymap, PS2KBD_KEYMAP_SIZE); +  memcpy(shiftkeymap, keymaps->shiftkeymap, PS2KBD_KEYMAP_SIZE); +  memcpy(keycap, keymaps->keycap, PS2KBD_KEYMAP_SIZE); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_setctrlmap(u8 *ctrlmap) + +{ +  //printf("ioctl_setctrlmap %p\n", ctrlmap); +  WaitSema(lineSema); +  memcpy(control_map, ctrlmap, PS2KBD_KEYMAP_SIZE); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_setaltmap(u8 *altmap) + +{ +  //printf("ioctl_setaltmap %p\n", altmap); +  WaitSema(lineSema); +  memcpy(alt_map, altmap, PS2KBD_KEYMAP_SIZE); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_setspecialmap(u8 *special) + +{ +  //printf("ioctl_setspecialmap %p\n", special); +  WaitSema(lineSema); +  memcpy(special_keys, special, PS2KBD_KEYMAP_SIZE); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_resetkeymap() +     /* Reset keymap to default US variety */ + +{ +  //printf("ioctl_resetkeymap()\n"); +  WaitSema(lineSema); +  memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE); +  memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE); +  memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE); +  memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE); +  memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE); +  memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_flushbuffer() +     /* Flush the internal buffer */ + +{ +  //printf("ioctl_flushbuffer()\n"); +  WaitSema(lineSema); +  flushbuffer(); +  SignalSema(lineSema); +} + +void ps2kbd_rpc_setleds(u8 ledStatus) + +{ +  int devLoop; +  kbd_dev *dev; + +  //printf("ioctl_setleds %d\n", ledStatus); +  ledStatus &= PS2KBD_LED_MASK; +  for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) +    { +      dev = devices[devLoop]; +      if(dev) +	{ +	  if(ledStatus != dev->ledStatus) +	    { +	      dev->ledStatus = ledStatus & PS2KBD_LED_MASK; +	      UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200, +				 dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, dev); +	    } +	} +    } +} + +void ps2kbd_rpc_setrepeatrate(u32 rate) +{ +  kbd_repeatrate = rate; +} + +int kbd_read(void *buf, int size) +{ +	int count = 0; +	char *data = (char *) buf; + +	if(kbd_readmode == PS2KBD_READMODE_RAW) +		size &= ~1; /* Ensure size of a multiple of 2 */ + +	if (PollSema(bufferSema) >= 0) { +		SignalSema(bufferSema); +		if (WaitSema(lineSema) >= 0) { +			while((count < size) && (lineStartP != lineEndP)) { +				data[count] = lineBuffer[lineStartP++]; +				lineStartP %= lineSize; +				count++; +				PollSema(bufferSema); /* Take off one count from the sema */ +			} +			SignalSema(lineSema); +		} +	} +	return count; +} + +void repeat_thread(void *arg) + +{ +  u32 eventmask; +  int devLoop; + +  for(;;) +    { +      WaitEventFlag(eventid, 0xFFFFFFFF, 0x01 | 0x10, &eventmask); +      //printf("Recieved event %08X\n", eventmask); +      for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) +	{ +	  if((eventmask & (1 << devLoop)) && (devices[devLoop])) +	    { +	      int tempPos = 0; + +	      WaitSema(lineSema); +	      if(lineStartP < lineEndP) +		{ +		  tempPos = lineStartP + lineSize; +		} +	      else +		{ +		  tempPos = lineStartP; +		} + +	      if((devices[devLoop]->repeatkeys[0]) && (devices[devLoop]->repeatkeys[1])) +		{ +		  if(lineEndP != (tempPos - 2)) +		    { +		      lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0]; +		      lineEndP %= lineSize;	       +		      lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[1]; +		      lineEndP %= lineSize; +		      SignalSema(bufferSema); +		      SignalSema(bufferSema); +		    } +		} +	      else if(devices[devLoop]->repeatkeys[0]) +		{ +		  if(lineEndP != (tempPos - 1)) +		    { +		      lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0]; +		      lineEndP %= lineSize;	       +		      SignalSema(bufferSema); +		    } +		} + +	      SignalSema(lineSema); +	    } +	} +    } +} + +int init_repeatthread() +     /* Creates a thread to handle key repeats */ +{ +  iop_thread_t param; +  iop_event_t event; + +  event.attr = 0; +  event.option = 0; +  event.bits = 0; +  eventid = CreateEventFlag(&event); + +  param.attr         = TH_C; +  param.thread    = repeat_thread; +  param.priority     = 40; +  param.stacksize    = 0x800; +  param.option       = 0; + +  repeat_tid = CreateThread(¶m); +  if (repeat_tid > 0) { +    StartThread(repeat_tid, 0); +    return 0; +  } +  else  +    { +      return 1; +    } +} + +static unsigned long retKey; + +void *ps2kbd_rpc_server(int fno, void *data, int size) { +	retKey = 0; +	switch (fno) { +	case KBD_RPC_SETREADMODE: +		ps2kbd_rpc_setreadmode(*(u32 *)data); +		break; +	case KBD_RPC_SETKEYMAP: +		ps2kbd_rpc_setkeymap((kbd_keymap *) data); +		break; +	case KBD_RPC_SETALTMAP: +		ps2kbd_rpc_setaltmap((u8 *) data); +		break; +	case KBD_RPC_SETCTRLMAP: +		ps2kbd_rpc_setctrlmap((u8 *) data); +		break; +	case KBD_RPC_SETSPECIALMAP: +		ps2kbd_rpc_setspecialmap((u8 *) data); +		break; +	case KBD_RPC_FLUSHBUFFER: +		ps2kbd_rpc_flushbuffer(); +		break; +	case KBD_RPC_SETLEDS: +		ps2kbd_rpc_setleds(*(u8*) data); +		break; +	case KBD_RPC_RESETKEYMAP: +		ps2kbd_rpc_resetkeymap(); +		break; +	case KBD_RPC_SETREPEATRATE: +		ps2kbd_rpc_setrepeatrate(*(u32 *) data); +		break; +	case KBD_RPC_READRAW: +		kbd_read(&retKey, 2); +		return &retKey; +	case KBD_RPC_READKEY: +		kbd_read(&retKey, 1); +		return &retKey; +	default: +		printf("Ps2Kbd: Unknown RPC command %d\n", fno); +		break; +	} +	return NULL; +} + +struct t_SifRpcDataQueue qd; +struct t_SifRpcServerData sd0; +void *rpcRcvBuf; + +void ps2kbd_start_rpc(unsigned long tid) { +	rpcRcvBuf = AllocSysMemory(0, 3 * PS2KBD_KEYMAP_SIZE, NULL); +	printf("Ps2Kbd: starting RPC server\n"); +	SifInitRpc(0); + +	SifSetRpcQueue(&qd, tid); +	SifRegisterRpc(&sd0, PS2KBD_RPC_ID, ps2kbd_rpc_server, rpcRcvBuf, 0, 0, &qd); +	SifRpcLoop(&qd); +} + +int ps2kbd_init_rpc(void) { +	struct _iop_thread param; +	int th; + +	param.attr         = 0x02000000; +	param.thread       = (void*)ps2kbd_start_rpc; +	param.priority 	  = 40; +	param.stacksize    = 0x800; +	param.option      = 0; + +	th = CreateThread(¶m); + +	if (th > 0)	{ +		StartThread(th, (void *)th); +		return 0; +	} else +		return -1; +} + +int ps2kbd_init() { +  int ret; +  iop_sema_t s; + +  s.initial = 1; +  s.max = 1; +  s.option = 0; +  s.attr = 0; +  lineSema = CreateSema(&s); +  if(lineSema <= 0) +    { +      printf("Error creating sema\n"); +      return 1; +    } + +  s.initial = 0; +  s.max = PS2KBD_DEFLINELEN; +  s.option = 0; +  s.attr = 0; +  bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */ +  if(bufferSema <= 0) +    { +      printf("Error creating buffer sema\n"); +      return 1; +    } + +  lineBuffer = (u8 *) AllocSysMemory(0, PS2KBD_DEFLINELEN, NULL); +  if(lineBuffer == NULL) +    { +      printf("Error allocating line buffer\n"); +      return 1; +    } +  lineStartP = 0; +  lineEndP = 0; +  lineSize = PS2KBD_DEFLINELEN; +  memset(lineBuffer, 0, PS2KBD_DEFLINELEN); +   +  memset(devices, 0, sizeof(kbd_dev *) * PS2KBD_MAXDEV); +  dev_count = 0; +  kbd_readmode = PS2KBD_READMODE_NORMAL; +  kbd_repeatrate = PS2KBD_DEFREPEATRATE; +  memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE); +  memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE); +  memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE); +  memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE); +  memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE); +  memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE); + +  ps2kbd_init_rpc(); +  init_repeatthread(); + +  ret = UsbRegisterDriver(&kbd_driver); +  if(ret != USB_RC_OK) +    { +      printf("Error registering USB devices\n"); +      return 1; +    } + +  printf("UsbRegisterDriver %d\n", ret); + +  return 0; +} diff --git a/backends/platform/ps2/iop/rpckbd/src/us_keymap.h b/backends/platform/ps2/iop/rpckbd/src/us_keymap.h new file mode 100644 index 0000000000..57f0686cd3 --- /dev/null +++ b/backends/platform/ps2/iop/rpckbd/src/us_keymap.h @@ -0,0 +1,1579 @@ +/* +# _____     ___ ____     ___ ____ +#  ____|   |    ____|   |        | |____| +# |     ___|   |____ ___|    ____| |    \    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 __US_KEYMAP_H__ +#define __US_KEYMAP_H__ + +/* Default US keymap */ + +u8 us_keymap[PS2KBD_KEYMAP_SIZE] =  +  {  +    0, +    0, +    0, +    0, +    'a', +    'b', +    'c', +    'd', +    'e', +    'f', +    'g', +    'h', +    'i', +    'j', +    'k', +    'l', +    'm', +    'n', +    'o', +    'p', +    'q', +    'r', +    's', +    't', +    'u', +    'v', +    'w', +    'x', +    'y', +    'z', +    '1', +    '2', +    '3', +    '4', +    '5', +    '6', +    '7', +    '8', +    '9', +    '0', +    10, /* line feed */ +    0, /* Esc */ +    0x7,/* BS */ +    0x9, /* TAB */ +    0x20, +    '-', +    '=', +    '[', +    ']', +    '\\', +    '#', +    ';', +    '\'', +    '`', +    ',', +    '.', +    '/', +    0, /* CL */ +    0, // F1 +    0, // F2 +    0, // F3 +    0, // F4 +    0, // F5 +    0, // F6 +    0, // F7 +    0, // F8  +    0, // F9 +    0, // F10 +    0, // F11 +    0, // F12 +    0, // PrintScr +    0, // Scroll Lock +    0, // Pause +    0, // Insert +    0, // Home  +    0, // Pg Up +    0, // Delete +    0, // End +    0, // Pg Down +    0, // Right +    0, // Left +    0, // Down +    0, // Up +    0, // Numlock +    '/', // Keypad  +    '*', +    '-', +    '+', +    10, +    '1', +    '2', +    '3', +    '4', +    '5', +    '6', +    '7', +    '8', +    '9', +    '0', +    '.', +    '\\', +    0, +    0, +    '=', +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +  }; + +u8 us_shiftkeymap[PS2KBD_KEYMAP_SIZE] =  +  { +    0, +    0, +    0, +    0, +    'A', +    'B', +    'C', +    'D', +    'E', +    'F', +    'G', +    'H', +    'I', +    'J', +    'K', +    'L', +    'M', +    'N', +    'O', +    'P', +    'Q', +    'R', +    'S', +    'T', +    'U', +    'V', +    'W', +    'X', +    'Y', +    'Z', +    '!', +    '@', +    '#', +    '$', +    '%', +    '^', +    '&', +    '*', +    '(', +    ')', +    10, /* line feed */ +    0, /* Esc */ +    0x7,/* BS */ +    0x9, /* TAB */ +    0x20, +    '_', +    '+', +    '{', +    '}', +    '|', +    '~', +    ':', +    '"', +    '~', +    '<', +    '>', +    '?', +    0, /* CL */ +    0, // F1 +    0, // F2 +    0, // F3 +    0, // F4 +    0, // F5 +    0, // F6 +    0, // F7 +    0, // F8  +    0, // F9 +    0, // F10 +    0, // F11 +    0, // F12 +    0, // PrintScr +    0, // Scroll Lock +    0, // Pause +    0, // Insert +    0, // Home  +    0, // Pg Up +    0, // Delete +    0, // End +    0, // Pg Down +    0, // Right +    0, // Left +    0, // Down +    0, // Up +    0, // Numlock +    '/', // Keypad  +    '*', +    '-', +    '+', +    10, +    '1', +    '2', +    '3', +    '4', +    '5', +    '6', +    '7', +    '8', +    '9', +    '0', +    '.', +    '\\', +    0, +    0, +    '=', +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +  }; + +u8 us_keycap[PS2KBD_KEYMAP_SIZE] =  +  { +    0, +    0, +    0, +    0, +    1, //a +    1, //b +    1, //c +    1, //d +    1, //e +    1, //f +    1,//g +    1,//h +    1,//i +    1,//j +    1,//k +    1,//l +    1,//m +    1,//n +    1,//o +    1,//p +    1,//q +    1,//r +    1,//s +    1,//t +    1,//u +    1,//v +    1,//w +    1,//x +    1,//y +    1,//z +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* line feed */ +    0, /* Esc */ +    0,/* BS */ +    0, /* TAB */ +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* CL */ +    0, // F1 +    0, // F2 +    0, // F3 +    0, // F4 +    0, // F5 +    0, // F6 +    0, // F7 +    0, // F8  +    0, // F9 +    0, // F10 +    0, // F11 +    0, // F12 +    0, // PrintScr +    0, // Scroll Lock +    0, // Pause +    0, // Insert +    0, // Home  +    0, // Pg Up +    0, // Delete +    0, // End +    0, // Pg Down +    0, // Right +    0, // Left +    0, // Down +    0, // Up +    0, // Numlock +    0, // Keypad  +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +  }; + +u8 us_special_keys[PS2KBD_KEYMAP_SIZE] = {  + +    0, +    0, +    0, +    0, +    0, //a +    0, //b +    0, //c +    0, //d +    0, //e +    0, //f +    0,//g +    0,//h +    0,//i +    0,//j +    0,//k +    0,//l +    0,//m +    0,//n +    0,//o +    0,//p +    0,//q +    0,//r +    0,//s +    0,//t +    0,//u +    0,//v +    0,//w +    0,//x +    0,//y +    0,//z +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* line feed */ +    0x1B, /* Esc */ +    0,/* BS */ +    0, /* TAB */ +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* CL */ +    1, // F1 +    2, // F2 +    3, // F3 +    4, // F4 +    5, // F5 +    6, // F6 +    7, // F7 +    8, // F8  +    9, // F9 +    10, // F10 +    11, // F11 +    12, // F12 +    32, // PrintScr +    33, // Scroll Lock +    34, // Pause +    35, // Insert +    36, // Home  +    37, // Pg Up +    38, // Delete +    39, // End +    40, // Pg Down +    41, // Right +    42, // Left +    43, // Down +    44, // Up +    0, // Numlock +    0, // Keypad /  +    0, // Keypad * +    0, // Keypad - +    0, // Keypad + +    0, // Keypad Enter +    39, // Keypad 1/End +    43, // Keypad 2/Down +    40, // Keypad 3/PageDn +    42, // Keypad 4/Left +    0, // Keypad 5 +    41, // Keypad 6/Right +    36, // Keypad 7/Home +    44, // Keypad 8/Up +    37, // Keypad 9/PageUp +    35, // Keypad 0/Insert +    38, // Keypad ./Delete +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +  }; + +u8 us_control_map[PS2KBD_KEYMAP_SIZE] = {  + +    0, +    0, +    0, +    0, +    1, //a +    2, //b +    3, //c +    4, //d +    5, //e +    6, //f +    7,//g +    8,//h +    9,//i +    10,//j +    11,//k +    12,//l +    13,//m +    14,//n +    15,//o +    16,//p +    17,//q +    18,//r +    19,//s +    20,//t +    21,//u +    22,//v +    23,//w +    24,//x +    25,//y +    26,//z +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* line feed */ +    0, /* Esc */ +    0,/* BS */ +    0, /* TAB */ +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* CL */ +    0, // F1 +    0, // F2 +    0, // F3 +    0, // F4 +    0, // F5 +    0, // F6 +    0, // F7 +    0, // F8  +    0, // F9 +    0, // F10 +    0, // F11 +    0, // F12 +    0, // PrintScr +    0, // Scroll Lock +    0, // Pause +    0, // Insert +    0, // Home  +    0, // Pg Up +    0, // Delete +    0, // End +    0, // Pg Down +    0, // Right +    0, // Left +    0, // Down +    0, // Up +    0, // Numlock +    0, // Keypad  +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +}; + +u8 us_alt_map[PS2KBD_KEYMAP_SIZE] = {  + +    0, +    0, +    0, +    0, +    128, //a +    129, //b +    130, //c +    131, //d +    132, //e +    133, //f +    134,//g +    135,//h +    136,//i +    137,//j +    138,//k +    139,//l +    140,//m +    141,//n +    142,//o +    143,//p +    144,//q +    145,//r +    146,//s +    147,//t +    148,//u +    149,//v +    150,//w +    151,//x +    152,//y +    154,//z +    155, +    156, +    157, +    158, +    159, +    160, +    161, +    162, +    163, +    164, +    165, /* line feed */ +    0, /* Esc */ +    0,/* BS */ +    0, /* TAB */ +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, /* CL */ +    0, // F1 +    0, // F2 +    0, // F3 +    0, // F4 +    0, // F5 +    0, // F6 +    0, // F7 +    0, // F8  +    0, // F9 +    0, // F10 +    0, // F11 +    0, // F12 +    0, // PrintScr +    0, // Scroll Lock +    0, // Pause +    0, // Insert +    0, // Home  +    0, // Pg Up +    0, // Delete +    0, // End +    0, // Pg Down +    0, // Right +    0, // Left +    0, // Down +    0, // Up +    0, // Numlock +    0, // Keypad  +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0, +    0 +  }; + +#endif diff --git a/backends/platform/ps2/irxboot.cpp b/backends/platform/ps2/irxboot.cpp index 327e5bdc71..65d1e243eb 100644 --- a/backends/platform/ps2/irxboot.cpp +++ b/backends/platform/ps2/irxboot.cpp @@ -43,7 +43,7 @@ IrxFile irxFiles[] = {  	{ "PADMAN",  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 },  	{ "CODYVDFS.IRX", SYSTEM, NOTHING, NULL, 0 },  	{ "SJPCM.IRX",    SYSTEM, NOTHING, NULL, 0 }, diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 28ced7b345..d4dd9aedcf 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -54,9 +54,11 @@  #include "graphics/surface.h"  #include "graphics/font.h"  #include "backends/timer/default/default-timer.h" -#include "sound/mixer.h" +#include "sound/mixer_intern.h"  #include "common/events.h"  #include "backends/platform/ps2/ps2debug.h" +#include "backends/fs/ps2/ps2-fs-factory.h" +  // asm("mfc0	%0, $9\n" : "=r"(tickStart));  extern void *_gp; @@ -309,7 +311,9 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) {  void OSystem_PS2::init(void) {  	sioprintf("Timer...\n");  	_scummTimerManager = new DefaultTimerManager(); -	_scummMixer = new Audio::Mixer(); +	_scummMixer = new Audio::MixerImpl(this); +	_scummMixer->setOutputRate(44100); +	_scummMixer->setReady(true);  	initTimer();  	sioprintf("Starting SavefileManager\n"); @@ -410,7 +414,8 @@ void OSystem_PS2::soundThread(void) {  			// we have to produce more samples, call sound mixer  			// the scratchpad at 0x70000000 is used as temporary soundbuffer  			//_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  			 __asm__ ( @@ -534,10 +539,6 @@ Common::TimerManager *OSystem_PS2::getTimerManager() {  	return _scummTimerManager;  } -int OSystem_PS2::getOutputSampleRate(void) const { -	return 48000; -} -  Audio::Mixer *OSystem_PS2::getMixer() {  	return _scummMixer;  } @@ -546,6 +547,10 @@ Common::SaveFileManager *OSystem_PS2::getSavefileManager(void) {  	return _saveManager;  } +FilesystemFactory *OSystem_PS2::getFilesystemFactory() { +	return &Ps2FilesystemFactory::instance(); +} +  void OSystem_PS2::setShakePos(int shakeOffset) {  	_screen->setShakePos(shakeOffset);  } diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index 9dbe9be553..08975ab2c8 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -33,6 +33,7 @@ class DefaultTimerManager;  class Gs2dScreen;  class Ps2Input;  class Ps2SaveFileManager; +// class Ps2FilesystemFactory;  struct IrxReference;  #define MAX_MUTEXES 16 @@ -48,7 +49,7 @@ namespace Common {  };  namespace Audio { -	class Mixer; +	class MixerImpl;  };  class OSystem_PS2 : public OSystem { @@ -87,7 +88,6 @@ public:  	virtual bool pollEvent(Common::Event &event);  	virtual Audio::Mixer *getMixer(); -	virtual int  getOutputSampleRate(void) const;  	virtual bool openCD(int drive);  	virtual bool pollCD(); @@ -112,6 +112,7 @@ public:  	virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);  	virtual Common::SaveFileManager *getSavefileManager(); +	virtual FilesystemFactory *getFilesystemFactory();  	virtual void getTimeAndDate(struct tm &t) const; @@ -133,7 +134,7 @@ private:  	void readRtcTime(void);  	DefaultTimerManager *_scummTimerManager; -	Audio::Mixer *_scummMixer; +	Audio::MixerImpl *_scummMixer;  	bool _mouseVisible; diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index aa27f388b9..ca09286c4d 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -2,10 +2,36 @@  # $URL$  # $Id$ +ENABLED=STATIC_PLUGIN +  #control build  DISABLE_SCALERS = true  DISABLE_HQ_SCALERS = true +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) +#ENABLE_HE = $(ENABLED) +ENABLE_AGI = $(ENABLED) +ENABLE_AGOS = $(ENABLED) +#ENABLE_CINE = $(ENABLED) +#ENABLE_CRUISE = $(ENABLED) +ENABLE_DRASCULA = $(ENABLED) +ENABLE_GOB = $(ENABLED) +#ENABLE_IGOR = $(ENABLED) +ENABLE_KYRA = $(ENABLED) +ENABLE_LURE = $(ENABLED) +#ENABLE_M4 = $(ENABLED) +#ENABLE_MADE = $(ENABLED) +#ENABLE_PARALLACTION = $(ENABLED) +#ENABLE_QUEEN = $(ENABLED) +#ENABLE_SAGA = $(ENABLED) +ENABLE_SKY = $(ENABLED) +ENABLE_SWORD1 = $(ENABLED) +ENABLE_SWORD2 = $(ENABLED) +#ENABLE_TINSEL = $(ENABLED) +#ENABLE_TOUCHE = $(ENABLED) + +  srcdir = ../../..  VPATH = $(srcdir)  HAVE_GCC3 = false @@ -63,6 +89,8 @@ OBJS := psp_main.o \  	kbd_l_c.o \  	trace.o +DEPDIR = .deps +  include $(srcdir)/Makefile.common  PSP_EBOOT_SFO = param.sfo diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp index 2d18b4bfd6..6e9b5980d4 100644 --- a/backends/platform/psp/osys_psp.cpp +++ b/backends/platform/psp/osys_psp.cpp @@ -72,7 +72,7 @@ const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = {  }; -OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0) { +OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0), _mixer(0) {  	memset(_palette, 0, sizeof(_palette)); @@ -99,11 +99,11 @@ OSystem_PSP::~OSystem_PSP() {  void OSystem_PSP::initBackend() {  	_savefile = new DefaultSaveFileManager(); -	_mixer = new Audio::MixerImpl(this);  	_timer = new DefaultTimerManager(); -	setSoundCallback(Audio::Mixer::mixCallback, _mixer);  	setTimerCallback(&timer_handler, 10); +	setupMixer(); +  	OSystem::initBackend();  } @@ -586,7 +586,15 @@ void OSystem_PSP::deleteMutex(MutexRef mutex) {  	SDL_DestroyMutex((SDL_mutex *)mutex);  } -bool OSystem_PSP::setSoundCallback(SoundProc proc, void *param) { +void OSystem_PSP::mixCallback(void *sys, byte *samples, int len) { +	OSystem_PSP *this_ = (OSystem_PSP *)sys; +	assert(this_); + +	if (this_->_mixer) +		this_->_mixer->mixCallback(samples, len); +} + +void OSystem_PSP::setupMixer(void) {  	SDL_AudioSpec desired;  	SDL_AudioSpec obtained; @@ -613,21 +621,29 @@ bool OSystem_PSP::setSoundCallback(SoundProc proc, void *param) {  	desired.format = AUDIO_S16SYS;  	desired.channels = 2;  	desired.samples = samples; -	desired.callback = proc; -	desired.userdata = param; +	desired.callback = mixCallback; +	desired.userdata = this; + +	assert(!_mixer); +	_mixer = new Audio::MixerImpl(this); +	assert(_mixer); +  	if (SDL_OpenAudio(&desired, &obtained) != 0) { -		return false; +		warning("Could not open audio: %s", SDL_GetError()); +		_samplesPerSec = 0; +		_mixer->setReady(false); +	} else { +		// Note: This should be the obtained output rate, but it seems that at +		// least on some platforms SDL will lie and claim it did get the rate +		// even if it didn't. Probably only happens for "weird" rates, though. +		_samplesPerSec = obtained.freq; +		 +		// Tell the mixer that we are ready and start the sound processing +		_mixer->setOutputRate(_samplesPerSec); +		_mixer->setReady(true); + +		SDL_PauseAudio(0);  	} -	// Note: This should be the obtained output rate, but it seems that at -	// least on some platforms SDL will lie and claim it did get the rate -	// even if it didn't. Probably only happens for "weird" rates, though. -	_samplesPerSec = obtained.freq; -	SDL_PauseAudio(0); -	return true; -} - -int OSystem_PSP::getOutputSampleRate() const { -	return _samplesPerSec;  }  void OSystem_PSP::quit() { diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h index 64514f6872..dca6ccb036 100644 --- a/backends/platform/psp/osys_psp.h +++ b/backends/platform/psp/osys_psp.h @@ -26,6 +26,7 @@  #include "common/scummsys.h"  #include "common/system.h"  #include "graphics/surface.h" +#include "sound/mixer_intern.h"  #include "backends/fs/psp/psp-fs-factory.h" @@ -71,7 +72,7 @@ protected:  	SceCtrlData pad;  	Common::SaveFileManager *_savefile; -	Audio::Mixer *_mixer; +	Audio::MixerImpl *_mixer;  	Common::TimerManager *_timer;  public: @@ -129,9 +130,8 @@ public:  	virtual void unlockMutex(MutexRef mutex);  	virtual void deleteMutex(MutexRef mutex); -	typedef void (*SoundProc)(void *param, byte *buf, int len); -	virtual bool setSoundCallback(SoundProc proc, void *param); -	virtual int getOutputSampleRate() const; +	static void mixCallback(void *sys, byte *samples, int len); +	virtual void setupMixer(void);  	Common::SaveFileManager *getSavefileManager() { return _savefile; }  	Audio::Mixer *getMixer() { return _mixer; } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 290fe63663..76ac91c282 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -191,7 +191,7 @@ OSystem_SDL::OSystem_SDL()  OSystem_SDL::~OSystem_SDL() {  	SDL_RemoveTimer(_timerID); -	SDL_CloseAudio(); +	closeMixer();  	free(_dirtyChecksums);  	free(_currentPalette); @@ -199,7 +199,6 @@ OSystem_SDL::~OSystem_SDL() {  	free(_mouseData);  	delete _savefile; -	delete _mixer;  	delete _timer;  } @@ -306,7 +305,7 @@ void OSystem_SDL::quit() {  	SDL_ShowCursor(SDL_ENABLE);  	SDL_RemoveTimer(_timerID); -	SDL_CloseAudio(); +	closeMixer();  	free(_dirtyChecksums);  	free(_currentPalette); @@ -314,7 +313,6 @@ void OSystem_SDL::quit() {  	free(_mouseData);  	delete _savefile; -	delete _mixer;  	delete _timer;  	SDL_Quit(); @@ -389,14 +387,110 @@ void OSystem_SDL::deleteMutex(MutexRef mutex) {  #pragma mark --- Audio ---  #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) {  	OSystem_SDL *this_ = (OSystem_SDL *)sys;  	assert(this_); +	assert(this_->_mixer); -	if (this_->_mixer) -		this_->_mixer->mixCallback(samples, len); +	this_->_mixer->mixCallback(samples, len);  } +#endif +  void OSystem_SDL::setupMixer() {  	SDL_AudioSpec desired;  	SDL_AudioSpec obtained; @@ -443,10 +537,31 @@ void OSystem_SDL::setupMixer() {  		// Tell the mixer that we are ready and start the sound processing  		_mixer->setOutputRate(_samplesPerSec);  		_mixer->setReady(true); + +#ifdef MIXER_DOUBLE_BUFFERING +		initThreadedMixer(_mixer, obtained.samples * 4); +#endif + +		// start the sound system  		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() {  	assert(_mixer);  	return _mixer; diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 8a94a17b00..4ad588f5f5 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -51,6 +51,15 @@ namespace Common {  #define USE_OSD	1  #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 {  	GFX_NORMAL = 0, @@ -137,6 +146,8 @@ public:  	virtual void setupMixer();  	static void mixCallback(void *s, byte *samples, int len); +	virtual void closeMixer(); +  	virtual Audio::Mixer *getMixer();  	// Poll CD status @@ -369,6 +380,23 @@ protected:  	 */  	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;  	Audio::MixerImpl *_mixer; @@ -377,7 +405,7 @@ protected:  	Common::TimerManager *_timer; - +protected:  	void addDirtyRgnAuto(const byte *buf);  	void makeChecksums(const byte *buf); diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl index 1e5e4dc0c8..5d85fc03a2 100644 --- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl +++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl @@ -226,28 +226,31 @@  			$VariationSets{'ALL'}{'all'} = "$DefaultFeatures @WorkingEngines @EnablableSubEngines";  		# now one for each ready-for-release engine -	 +		if (0) +		{  			foreach (@WorkingEngines)  			{  				$VariationSets{'ALL'}{$_} = "$DefaultFeatures $_";  			}  			# 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 -	 +		if (0) +		{  			foreach (@TestingEngines)  			{  				$VariationSets{'ALL'}{"test_$_"} = "$DefaultFeatures $_";  			} -	 +		}  		# 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) -			$VariationSets{'ALL'}{'saga_mini'} = "saga"; +			#$VariationSets{'ALL'}{'saga_mini'} = "saga";  			# 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  			#$VariationSets{'S60v2'}{'test_sword'} = "$DefaultFeatures mpeg2 sword1 sword2"; diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp index dfeb24d825..660b0c69ed 100644 --- a/backends/platform/symbian/src/SymbianOS.cpp +++ b/backends/platform/symbian/src/SymbianOS.cpp @@ -33,7 +33,7 @@  #include "gui/Actions.h"  #include "gui/Key.h"  #include "gui/message.h" - +#include "sound/mixer_intern.h"  #include "..\..\sdl\main.cpp"  #ifdef SAMPLES_PER_SEC_8000 // the GreanSymbianMMP format cannot handle values for defines :( @@ -42,10 +42,22 @@    #define SAMPLES_PER_SEC 16000  #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" ///////////////////////////////////////////////////  namespace Symbian { + +  // Show a simple Symbian Info win with Msg & exit  void FatalError(const char *msg) {  	TPtrC8 msgPtr((const TUint8 *)msg); @@ -246,9 +258,9 @@ void OSystem_SDL_Symbian::symbianMixCallback(void *sys, byte *samples, int len)  	if (!this_->_mixer)  		return; -#ifdef S60 +#if defined (S60) && !defined(S60V3)  	// If not stereo then we need to downmix -	if (_channels != 2) { +	if (this_->_mixer->_channels != 2) {  		this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2);  		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) {  	TSymbianFileEntry* fileEntry = new TSymbianFileEntry; +	fileEntry->iInputPos = KErrNotFound;  	if (fileEntry != NULL) {  		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) { -	TPtr8 pointer( (unsigned char*) ptr, size*numItems); +	TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle)); +	TUint32 totsize = size*numItems; +	TPtr8 pointer ( (unsigned char*) ptr, totsize); + +	// 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); +		} -	((TSymbianFileEntry*)(handle))->iFileHandle.Read(pointer); +		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;  } @@ -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) {  	TPtrC8 pointer( (unsigned char*) ptr, size*numItems); +	((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;  	if (((TSymbianFileEntry*)(handle))->iFileHandle.Write(pointer) == KErrNone) {  		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) {  	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; -		if (((TSymbianFileEntry*)(handle))->iFileHandle.Size(size) == KErrNone) { -			if (pos == size) +		if (entry->iFileHandle.Size(size) == KErrNone) { +			if(entry->iInputPos == KErrNotFound && pos == size) 			  				return true; + +			if(entry->iInputPos != KErrNotFound && pos == size && entry->iInputPos == entry->iInputBufferLen) +				return true; +  			return false;  		}  	} @@ -549,6 +624,7 @@ long int symbian_ftell(FILE* handle) {  }  int symbian_fseek(FILE* handle, long int offset, int whence) { +  	TSeek seekMode = ESeekStart;  	TInt pos = offset; @@ -564,6 +640,8 @@ int symbian_fseek(FILE* handle, long int offset, int whence) {  		break;  	} +	 +	((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;  	return ((TSymbianFileEntry*)(handle))->iFileHandle.Seek(seekMode, pos);  } diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp index 2667ecb69d..9e708345c5 100644 --- a/backends/platform/wii/osystem.cpp +++ b/backends/platform/wii/osystem.cpp @@ -91,7 +91,7 @@ void OSystem_Wii::initBackend() {  	_startup_time = gettime();  	_savefile = new DefaultSaveFileManager(); -	_mixer = new Audio::Mixer(); +	_mixer = new Audio::MixerImpl(this);  	_timer = new DefaultTimerManager();  	initGfx(); diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h index 2a168fd0b7..7fbc560b1a 100644 --- a/backends/platform/wii/osystem.h +++ b/backends/platform/wii/osystem.h @@ -31,7 +31,7 @@  #include "backends/saves/default/default-saves.h"  #include "backends/timer/default/default-timer.h"  #include "graphics/surface.h" -#include "sound/mixer.h" +#include "sound/mixer_intern.h"  #include <gctypes.h>  #include <gccore.h> @@ -96,7 +96,7 @@ private:  protected:  	Common::SaveFileManager *_savefile; -	Audio::Mixer *_mixer; +	Audio::MixerImpl *_mixer;  	DefaultTimerManager *_timer;  public: @@ -159,7 +159,6 @@ public:  	virtual void deleteMutex(MutexRef mutex);  	typedef void (*SoundProc)(void *param, byte *buf, int len); -	virtual int getOutputSampleRate() const;  	virtual void quit(); diff --git a/backends/platform/wii/osystem_sfx.cpp b/backends/platform/wii/osystem_sfx.cpp index 16b2f3b055..0a225e80c7 100644 --- a/backends/platform/wii/osystem_sfx.cpp +++ b/backends/platform/wii/osystem_sfx.cpp @@ -36,9 +36,6 @@ static bool sfx_thread_quit = false;  static u8 sb = 0;  static u8 *sound_buffer[2]; -static OSystem_Wii::SoundProc sound_proc = NULL; -static void *proc_param = NULL; -  static void audio_switch_buffers() {  	AUDIO_StopDMA();  	AUDIO_InitDMA((u32) sound_buffer[sb], SFX_THREAD_FRAG_SIZE); @@ -48,6 +45,7 @@ static void audio_switch_buffers() {  }  static void * sfx_thread_func(void *arg) { +	Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg;  	u8 next_sb;  	while (true) { @@ -57,7 +55,7 @@ static void * sfx_thread_func(void *arg) {  			break;  		next_sb = sb ^ 1; -		sound_proc(proc_param, sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE); +		mixer->mixCallback(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE);  		DCFlushRange(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE);  		sb = next_sb; @@ -75,7 +73,7 @@ void OSystem_Wii::initSfx() {  	LWP_InitQueue(&sfx_queue); -	s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, NULL, sfx_stack, +	s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, _mixer, sfx_stack,  								SFX_THREAD_STACKSIZE, SFX_THREAD_PRIO);  	if (res) { @@ -95,9 +93,7 @@ void OSystem_Wii::initSfx() {  	DCFlushRange(sound_buffer[0], SFX_THREAD_FRAG_SIZE);  	DCFlushRange(sound_buffer[1], SFX_THREAD_FRAG_SIZE); -	sound_proc = Audio::Mixer::mixCallback; -	proc_param = _mixer; - +	_mixer->setOutputRate(48000);  	_mixer->setReady(true);  	AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); @@ -127,7 +123,3 @@ void OSystem_Wii::deinitSfx() {  	}  } -int OSystem_Wii::getOutputSampleRate() const { -	return 48000; -} - diff --git a/backends/platform/wince/missing/missing.cpp b/backends/platform/wince/missing/missing.cpp index 86d93dcb88..c760b1f7df 100644 --- a/backends/platform/wince/missing/missing.cpp +++ b/backends/platform/wince/missing/missing.cpp @@ -1,8 +1,34 @@ -/* MISSING.C -   Implementation for standard and semi-standard C library calls missing in WinCE -   environment. -   by Vasyl Tsvirkunov -*/ +/* 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$ + * + */ + +/* Original code: + * Implementation for standard and semi-standard C library calls missing in WinCE + * environment. + * by Vasyl Tsvirkunov + */ +  #include <windows.h>  #include <tchar.h> @@ -17,19 +43,8 @@  #include "time.h"  #include "dirent.h" -/* forward declaration */ - -#if _WIN32_WCE < 300 - -#define _STDAFX_H -#include "portdefs.h" - -#else -  char *strdup(const char *strSource); -#endif -  #ifdef __GNUC__  #define EXT_C extern "C"  #else @@ -40,19 +55,27 @@ char *strdup(const char *strSource);  void *bsearch(const void *key, const void *base, size_t nmemb,  			  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;  }  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];  	HANDLE handle;  	int len; @@ -63,8 +86,7 @@ int stat(const char *fname, struct stat *ss)  	/* Special case (dummy on WinCE) */  	len = strlen(fname);  	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 */  		memset(ss, 0, sizeof(struct stat));  		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);  	handle = FindFirstFile(fnameUnc, &wfd); +	FindClose(handle);  	if (handle == INVALID_HANDLE_VALUE)  		return -1;  	else @@ -83,20 +106,16 @@ int stat(const char *fname, struct stat *ss)  		ss->st_size = wfd.nFileSizeLow;  		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  			ss->st_mode |= S_IFDIR; - -		FindClose(handle);  	}  	return 0;  }  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];  	char* plast; -	if (cwd[0] == 0) -	{ +	if (cwd[0] == 0) {  		GetModuleFileName(NULL, fileUnc, MAX_PATH);  		WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);  		plast = strrchr(cwd, '\\'); @@ -114,8 +133,7 @@ EXT_C char *getcwd(char *buffer, int maxlen)  #ifdef __GNUC__  #undef GetCurrentDirectory  #endif -EXT_C void GetCurrentDirectory(int len, char *buf) -{ +EXT_C void GetCurrentDirectory(int len, char *buf) {  	getcwd(buf,len);  }; @@ -125,26 +143,22 @@ fully qualified paths refer to root folder rather  than current folder (concept not implemented in CE).  */  #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];  	if (!fname || fname[0] == '\0')  		return NULL; -	if (fname[0] != '\\' && fname[0] != '/') -	{ +	if (fname[0] != '\\' && fname[0] != '/') {  		getcwd(fullname, MAX_PATH);  		strncat(fullname, "\\", MAX_PATH-strlen(fullname)-1);  		strncat(fullname, fname, MAX_PATH-strlen(fullname)-strlen(fname));  		return fopen(fullname, fmode); -	} -	else +	} else  		return fopen(fname, fmode);  }  /* Remove file by name */ -int remove(const char* path) -{ +int remove(const char* path) {  	TCHAR pathUnc[MAX_PATH+1];  	MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);  	return !DeleteFile(pathUnc); @@ -158,14 +172,22 @@ int _access(const char *path, int mode) {  	WIN32_FIND_DATA ffd;  	HANDLE h=FindFirstFile(fname, &ffd); +	FindClose(h);  	if (h == INVALID_HANDLE_VALUE)  		return -1;  //Can't find file -	FindClose(h); -	if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) -		return 0; //Always return success if target is directory and exists +	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 +	}  	switch (mode) {  		case 00: //Check existence  			return 0; @@ -183,8 +205,7 @@ int _access(const char *path, int mode) {  #ifndef __GNUC__  /* Limited dirent implementation. Used by UI.C and DEVICES.C */ -DIR* opendir(const char* fname) -{ +DIR* opendir(const char* fname) {  	DIR* pdir;  	char fnameMask[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 */  	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);  		return NULL; -	} -	else -	{ +	} else {  		WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);  		pdir->dd_dir.d_name = strdup(nameFound); @@ -224,34 +242,25 @@ DIR* opendir(const char* fname)  	return pdir;  } -struct dirent*	readdir(DIR* dir) -{ +struct dirent* readdir(DIR* dir) {  	char nameFound[MAX_PATH+1];  	static struct dirent dummy; -	if (dir->dd_stat == 0) -	{ +	if (dir->dd_stat == 0) {  		dummy.d_name = ".";  		dummy.d_namlen = 1;  		dir->dd_stat ++;  		return &dummy; -	} -	else if (dir->dd_stat == 1) -	{ +	} else if (dir->dd_stat == 1) {  		dummy.d_name = "..";  		dummy.d_namlen = 2;  		dir->dd_stat ++;  		return &dummy; -	} -	else if (dir->dd_stat == 2) -	{ +	} else if (dir->dd_stat == 2) {  		dir->dd_stat++;  		return &dir->dd_dir; -	} -	else -	{ -		if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0) -		{ +	} else { +		if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0) {  			dir->dd_stat = -1;  			return NULL;  		} @@ -283,12 +292,6 @@ int closedir(DIR* dir)  	return 1;  } -/* in our case unlink is the same as remove */ -int unlink(const char* path) -{ -	return remove(path); -} -  /* Make directory, Unix style */  void mkdir(char* dirname, int mode)  { @@ -299,10 +302,8 @@ void mkdir(char* dirname, int mode)  	if (*path == '/')  		*path = '\\';  	/* Run through the string and attempt creating all subdirs on the path */ -	for (ptr = path+1; *ptr; ptr ++) -	{ -		if (*ptr == '\\' || *ptr == '/') -		{ +	for (ptr = path+1; *ptr; ptr ++) { +		if (*ptr == '\\' || *ptr == '/') {  			*ptr = 0;  			MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);  			CreateDirectory(pathUnc, 0); @@ -313,373 +314,40 @@ void mkdir(char* dirname, int mode)  	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) -#endif  {  	char* buffer; -	buffer = (char*)malloc(strlen(strSource)+1); +	size_z len = strlen(strSource)+1; +	buffer = (char*)malloc(len);  	if (buffer) -		strcpy(buffer, strSource); +		memcpy(buffer, strSource, len);  	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  #else // defined(__GNUC__)  #ifndef __MINGW32CE__ -int islower(int c) -{ +int islower(int c) {  	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');  } -int isalpha(int c) -{ -	return (islower(c) || (c>='A' && c<='Z')); +int isalpha(int c) { +	return ((c>='a' && c<='z') || (c>='A' && c<='Z'));  } -int isalnum(int c) -{ -	return (isalpha(c) || (c>='0' && c<='9')); -} - -int isprint(int c) -{ -	static char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~"; -	int i = 0, flag = 0; -	while ((punct[i] != 0) && (flag = (punct[i] != c))) -		i++; -	return (isalnum(c) || flag); +int isalnum(int c) { +	return ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'));  } -extern "C" int atexit(void (*function)(void)) -{ -	return 0; +int isprint(int c) { +	//static const char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~"; +	//return (isalnum(c) || strchr(punct, c)); +	return (32 <= c && c <= 126);	// based on BSD manpage  }  #endif | 
