Initial revision

svn-id: r3495
This commit is contained in:
Vasyl Tsvirkunov 2001-11-18 10:24:36 +00:00
parent 39939b50c2
commit cff30724fb
24 changed files with 4758 additions and 0 deletions

145
wince/PocketSCUMM.rc Normal file
View file

@ -0,0 +1,145 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "newres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""newres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_GAMESELECT DIALOG DISCARDABLE 0, 0, 121, 143
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Choose a Game"
FONT 8, "System"
BEGIN
PUSHBUTTON "Exit",IDCANCEL,64,127,50,10
PUSHBUTTON "Monkey Island 1",IDC_MONKEY,7,7,107,10
PUSHBUTTON "Monkey Island 2",IDC_MONKEY2,7,22,107,10
PUSHBUTTON "Fate of Atlantis",IDC_ATLANTIS,7,37,107,10
PUSHBUTTON "Fate of Atlantis Demo",IDC_PLAYFATE,7,52,107,10
PUSHBUTTON "Day Of The Tentacle",IDC_TENTACLE,7,67,107,10
PUSHBUTTON "Day Of The Tentacle Demo",IDC_DOTTDEMO,7,82,107,10
PUSHBUTTON "Sam && Max",IDC_SAMNMAX,7,97,107,10
PUSHBUTTON "Sam && Max Demo",IDC_SNMDEMO,7,112,107,10
END
/////////////////////////////////////////////////////////////////////////////
//
// Menubar
//
IDM_MENU MENU DISCARDABLE
BEGIN
POPUP "PocketSCUMM"
BEGIN
MENUITEM "Exit", IDC_EXIT
MENUITEM "About", IDC_ABOUT
MENUITEM SEPARATOR
MENUITEM "Landscape", IDC_LANDSCAPE
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Data
//
IDM_MENU SHMENUBAR DISCARDABLE
BEGIN
IDM_MENU, 1,
I_IMAGENONE, ID_POCKETSCUMM, TBSTATE_ENABLED,
TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_POCKETSCUMM, 0, 0,
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_GAMESELECT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 114
TOPMARGIN, 7
BOTTOMMARGIN, 136
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_CAP_POCKETSCUMM "PocketSCUMM"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

BIN
wince/PocketSCUMM.vco Normal file

Binary file not shown.

3061
wince/PocketSCUMM.vcp Normal file

File diff suppressed because it is too large Load diff

3
wince/missing/assert.h Normal file
View file

@ -0,0 +1,3 @@
/* Header is not present in Windows CE SDK */
#define assert(a) ;

2
wince/missing/conio.h Normal file
View file

@ -0,0 +1,2 @@
/* Header is not present in Windows CE SDK */

1
wince/missing/dir.h Normal file
View file

@ -0,0 +1 @@
/* Header is not present in Windows CE SDK */

1
wince/missing/direct.h Normal file
View file

@ -0,0 +1 @@
/* Header is not present in Windows CE SDK */

52
wince/missing/dirent.h Normal file
View file

@ -0,0 +1,52 @@
/* Header is not present in Windows CE SDK */
/* It would not be a bad idea to take this thing from gcc distro and port
it properly. For now only required part is ported. */
struct dirent
{
long d_ino; /* Always zero. */
unsigned short d_reclen; /* Always zero. */
unsigned short d_namlen; /* Length of name in d_name. */
char* d_name; /* File name. */
/* NOTE: The name in the dirent structure points to the name in the
* finddata_t structure in the DIR. */
};
/*
* This is an internal data structure. Good programmers will not use it
* except as an argument to one of the functions below.
*/
typedef struct
{
/* disk transfer area for this dir */
/* struct _finddata_t dd_dta; */
/* dirent struct to return from dir (NOTE: this makes this thread
* safe as long as only one thread uses a particular DIR struct at
* a time) */
struct dirent dd_dir;
/* _findnext handle */
long dd_handle;
/*
* Status of search:
* 0 = not started yet (next entry to read is first entry)
* -1 = off the end
* positive = 0 based index of next entry
*/
short dd_stat;
/* given path for dir with search pattern (struct is extended) */
char dd_name[1];
} DIR;
DIR* opendir (const char*);
struct dirent* readdir (DIR*);
int closedir (DIR*);
/*
void rewinddir (DIR*);
long telldir (DIR*);
void seekdir (DIR*, long);
*/

1
wince/missing/errno.h Normal file
View file

@ -0,0 +1 @@
/* Header is not present in Windows CE SDK */

1
wince/missing/fcntl.h Normal file
View file

@ -0,0 +1 @@
/* Header is not present in Windows CE SDK */

15
wince/missing/io.h Normal file
View file

@ -0,0 +1,15 @@
/* Header is not present in Windows CE SDK */
/* This stuff will live here until port configuration file is in place */
#define stricmp _stricmp
#define strdup _strdup
#define _HEAPOK 0
#define _heapchk() 0
#ifndef _FILE_DEFINED
typedef void FILE;
#define _FILE_DEFINED
#endif
FILE* wce_fopen(const char* fname, const char* fmode);
#define fopen wce_fopen

368
wince/missing/missing.cpp Normal file
View file

@ -0,0 +1,368 @@
/* MISSING.C
Implementation for standard and semi-standard C library calls missing in WinCE
environment.
(C) 2001 Vasyl Tsvirkunov
*/
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include "sys/stat.h"
#include "sys/time.h"
#include "time.h"
#include "dirent.h"
/* forward declaration */
char *strdup(const char *strSource);
/* Limited dirent implementation. Used by UI.C and DEVICES.C */
static WIN32_FIND_DATA wfd;
DIR* opendir(const char* fname)
{
DIR* pdir;
char fnameMask[MAX_PATH+1];
TCHAR fnameUnc[MAX_PATH+1];
char nameFound[MAX_PATH+1];
if(fname == NULL)
return NULL;
strcpy(fnameMask, fname);
if(!strlen(fnameMask) || fnameMask[strlen(fnameMask)-1] != '\\')
strncat(fnameMask, "\\", MAX_PATH-strlen(fnameMask)-1);
strncat(fnameMask, "*.*", MAX_PATH-strlen(fnameMask)-4);
pdir = (DIR*)malloc(sizeof(DIR)+strlen(fname));
pdir->dd_dir.d_ino = 0;
pdir->dd_dir.d_reclen = 0;
pdir->dd_dir.d_name = 0;
pdir->dd_dir.d_namlen = 0;
pdir->dd_handle = 0;
pdir->dd_stat = 0;
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)
{
free(pdir);
return NULL;
}
else
{
WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
pdir->dd_dir.d_name = strdup(nameFound);
pdir->dd_dir.d_namlen = strlen(nameFound);
}
return pdir;
}
struct dirent* readdir(DIR* dir)
{
char nameFound[MAX_PATH+1];
static struct dirent dummy;
if(dir->dd_stat == 0)
{
dummy.d_name = ".";
dummy.d_namlen = 1;
dir->dd_stat ++;
return &dummy;
}
else if(dir->dd_stat == 1)
{
dummy.d_name = "..";
dummy.d_namlen = 2;
dir->dd_stat ++;
return &dummy;
}
else if(dir->dd_stat == 2)
{
dir->dd_stat++;
return &dir->dd_dir;
}
else
{
if(FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0)
{
dir->dd_stat = -1;
return NULL;
}
WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
if(dir->dd_dir.d_name)
free(dir->dd_dir.d_name);
dir->dd_dir.d_name = strdup(nameFound);
dir->dd_dir.d_namlen = strlen(nameFound);
dir->dd_stat ++;
return &dir->dd_dir;
}
}
int closedir(DIR* dir)
{
if(dir == NULL)
return 0;
if(dir->dd_handle)
FindClose((HANDLE)dir->dd_handle);
if(dir->dd_dir.d_name)
free(dir->dd_dir.d_name);
free(dir);
return 1;
}
/* Very limited implementation of stat. Used by UI.C, MEMORY-P.C (latter is not critical) */
int stat(const char *fname, struct stat *ss)
{
TCHAR fnameUnc[MAX_PATH+1];
HANDLE handle;
int len;
if(fname == NULL || ss == NULL)
return -1;
/* Special case (dummy on WinCE) */
len = strlen(fname);
if(len >= 2 && fname[len-1] == '.' && fname[len-2] == '.' &&
(len == 2 || fname[len-3] == '\\'))
{
/* That's everything implemented so far */
memset(ss, 0, sizeof(struct stat));
ss->st_size = 1024;
ss->st_mode |= S_IFDIR;
return 0;
}
MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameUnc, MAX_PATH);
handle = FindFirstFile(fnameUnc, &wfd);
if(handle == INVALID_HANDLE_VALUE)
return -1;
else
{
/* That's everything implemented so far */
memset(ss, 0, sizeof(struct stat));
ss->st_size = wfd.nFileSizeLow;
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
ss->st_mode |= S_IFDIR;
FindClose(handle);
}
return 0;
}
/* Remove file by name */
int remove(const char* path)
{
TCHAR pathUnc[MAX_PATH+1];
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
return !DeleteFile(pathUnc);
}
/* 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)
{
char path[MAX_PATH+1];
TCHAR pathUnc[MAX_PATH+1];
char* ptr;
strncpy(path, dirname, MAX_PATH);
if(*path == '/')
*path = '\\';
/* Run through the string and attempt creating all subdirs on the path */
for(ptr = path+1; *ptr; ptr ++)
{
if(*ptr == '\\' || *ptr == '/')
{
*ptr = 0;
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
CreateDirectory(pathUnc, 0);
*ptr = '\\';
}
}
MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
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; }
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;
}
void rewind(FILE *stream)
{
fseek(stream, 0, SEEK_SET);
}
char *strdup(const char *strSource)
{
char* buffer;
buffer = (char*)malloc(strlen(strSource)+1);
if(buffer)
strcpy(buffer, strSource);
return buffer;
}
/* Used in UI.C */
char cwd[MAX_PATH+1] = "";
char *getcwd(char *buffer, int maxlen)
{
TCHAR fileUnc[MAX_PATH+1];
char* plast;
if(cwd[0] == 0)
{
GetModuleFileName(NULL, fileUnc, MAX_PATH);
WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
plast = strrchr(cwd, '\\');
if(plast)
*plast = 0;
/* Special trick to keep start menu clean... */
if(_stricmp(cwd, "\\windows\\start menu") == 0)
strcpy(cwd, "\\Apps");
}
if(buffer)
strncpy(buffer, cwd, maxlen);
return cwd;
}
/* Limited implementation of time.h. time_t formula is possibly incorrect. */
time_t time(time_t* res)
{
time_t t;
SYSTEMTIME st;
GetLocalTime(&st);
t = (time_t)(((((((st.wYear-1970)*12+st.wMonth)*31+st.wDay)*7+st.wDayOfWeek)*24+st.wHour)*60+st.wMinute)*60+st.wSecond);
if(res)
*res = t;
return t;
}
struct tm* localtime(time_t* timer)
{
static struct tm tmLocalTime;
unsigned long rem = *timer;
tmLocalTime.tm_sec = (short)(rem % 60);
rem /= 60;
tmLocalTime.tm_min = (short)(rem % 60);
rem /= 60;
tmLocalTime.tm_hour = (short)(rem % 24);
rem /= 24;
tmLocalTime.tm_mday = (short)(rem % 7);
rem /= 7;
tmLocalTime.tm_mday = (short)(rem % 31);
rem /= 31;
tmLocalTime.tm_mon = (short)(rem % 12);
rem /= 12;
tmLocalTime.tm_year = (short)(rem+1970);
return &tmLocalTime;
}
/* Very limited implementation of sys/time.h */
void gettimeofday(struct timeval* tp, void* dummy)
{
DWORD dt = GetTickCount();
tp->tv_sec = dt/1000;
tp->tv_usec = dt*1000;
}
void usleep(long usec)
{
long msec = usec/1000;
if(msec <= 0)
Sleep(0);
else
Sleep(msec);
}
/*
Windows CE fopen has non-standard behavior -- not
fully qualified paths refer to root folder rather
than current folder (concept not implemented in CE).
*/
#undef fopen
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] != '/')
{
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
return fopen(fname, fmode);
}
/* This may provide for better sync mechanism */
unsigned int clock()
{
return GetTickCount();
}
/* And why do people use this? */
void abort()
{
exit(1);
}
/*
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 "";
}

3
wince/missing/signal.h Normal file
View file

@ -0,0 +1,3 @@
/* Header is not present in Windows CE SDK */
/* Functionality is not critical -- Pocket PC devices do not have Ctrl+C */
#define signal(a,b)

23
wince/missing/sys/stat.h Normal file
View file

@ -0,0 +1,23 @@
/* Header is not present in Windows CE SDK */
#include <sys/types.h>
struct stat {
_dev_t st_dev;
_ino_t st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
_dev_t st_rdev;
_off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
#define _S_IFDIR 0040000 /* directory */
#define S_IFDIR _S_IFDIR
int stat(const char *, struct stat *);

10
wince/missing/sys/time.h Normal file
View file

@ -0,0 +1,10 @@
/* Header is not present in Windows CE SDK */
struct timeval
{
int tv_sec;
int tv_usec;
};
void gettimeofday(struct timeval* tp, void* dummy);
void usleep(long usec);

View file

@ -0,0 +1,5 @@
/* Header is not present in Windows CE SDK */
typedef unsigned short _ino_t;
typedef unsigned int _dev_t;
typedef long _off_t;

24
wince/missing/time.h Normal file
View file

@ -0,0 +1,24 @@
/* Header is not present in Windows CE SDK */
#ifndef A800_TIME_H
#define A800_TIME_H
#include <stdlib.h>
struct tm
{
short tm_year;
short tm_mon;
short tm_mday;
short tm_wday;
short tm_hour;
short tm_min;
short tm_sec;
};
time_t time(time_t* dummy);
struct tm* localtime(time_t* dummy);
unsigned int clock();
#endif

1
wince/missing/unistd.h Normal file
View file

@ -0,0 +1 @@
/* Header is not present in Windows CE SDK */

41
wince/newres.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef __NEWRES_H__
#define __NEWRES_H__
#if !defined(UNDER_CE)
#define UNDER_CE _WIN32_WCE
#endif
#if defined(_WIN32_WCE)
#if !defined(WCEOLE_ENABLE_DIALOGEX)
#define DIALOGEX DIALOG DISCARDABLE
#endif
#include <commctrl.h>
#define SHMENUBAR RCDATA
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
#include <aygshell.h>
#define AFXCE_IDR_SCRATCH_SHMENU 28700
#else
#define I_IMAGENONE (-2)
#define NOMENU 0xFFFF
#define IDS_SHNEW 1
#define IDM_SHAREDNEW 10
#define IDM_SHAREDNEWDEFAULT 11
#endif // _WIN32_WCE_PSPC
#define AFXCE_IDD_SAVEMODIFIEDDLG 28701
#endif // _WIN32_WCE
#ifdef RC_INVOKED
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#include "winuser.h" // extract from windows header
#include "winver.h"
#endif
#endif
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1)
#endif //__NEWRES_H__

624
wince/pocketpc.cpp Normal file
View file

@ -0,0 +1,624 @@
// ScummVM - Scumm Interpreter
// PocketSCUMM - PocketPC port of ScummVM. Based on the original Win32
// implementation by Ludvig Strigeus.
// Ported by Vasyl Tsvirkunov (vasyl@pacbell.net).
// Note: this is the very first version, implementing only basic functionality.
// Keyboard is not implemented, there is no way to access save/load game
// and the interpreter is hardcoded to one game (MI1 in this case). Later
// versions will get these limitations removed. Right now you should
// consider this port a proof of concept.
// To run PocketSCUMM, put PocketSCUMM.exe and game resources (MONKEY.000, MONKEY.001)
// in one folder (can be on storage card) and run the executable. Unused part of
// the screen below the image is split to two halves - tap on the left to press
// Escape (skip intro, etc.), tap on the right to change screen rotation.
// Another note: This file is very similar to windows.cpp in the core project. I was
// even thinking about integrating WinCE code there, I still may do it later.
// For ease of updating, non-trivial blocks identical to windows.cpp are marked
// with //{{ and //}} comments
// Consistent with 1.18
#include "stdafx.h"
#include <assert.h>
#include <aygshell.h>
#include "resource.h"
#include "scumm.h"
#include "screen.h"
#include "sound.h"
#include "gui.h"
#define USE_F_KEYS
#ifdef USE_F_KEYS
void setup_extra_windows(HWND hwndTop);
void adjust_extra_windows();
HWND hwndFKeys;
#endif
#define SAMPLES_PER_SEC 22050
#define BUFFER_SIZE (8192)
#define BITS_PER_SAMPLE 16
// Practically identical to the one in windows.cpp
class WndMan
{
HMODULE hInst;
HWND hWnd;
bool terminated;
public:
byte *_vgabuf;
Scumm *_scumm;
HANDLE _event;
DWORD _threadId;
HWAVEOUT _handle;
WAVEHDR _hdr[2];
public:
void init();
bool handleMessage();
void run();
void setPalette(byte *ctab, int first, int num);
void writeToScreen();
void prepare_header(WAVEHDR *wh, int i);
void sound_init();
static DWORD _stdcall sound_thread(WndMan *wm);
};
// Similar to Error in windows.cpp but has to take Unicode in account
void Error(LPCTSTR msg)
{
OutputDebugString(msg);
MessageBox(0, msg, TEXT("Error"), MB_ICONSTOP);
exit(1);
}
//{{
Scumm scumm;
ScummDebugger debugger;
Gui gui;
SoundEngine sound;
WndMan wm[1];
byte veryFastMode;
//}}
// WndProc is significantly port-specific
int mapKey(int key) {
if (key>=VK_F1 && key<=VK_F9) {
return key - VK_F1 + 315;
}
return key;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static SHACTIVATEINFO sai;
WndMan *wm = (WndMan*)GetWindowLong(hWnd, GWL_USERDATA);
switch (message)
{
case WM_CREATE:
memset(&sai, 0, sizeof(sai));
SHSipPreference(hWnd, SIP_INPUTDIALOG);
return 0;
case WM_DESTROY:
case WM_CLOSE:
GraphicsOff();
PostQuitMessage(0);
break;
case WM_ERASEBKGND:
{
RECT rc;
HDC hDC;
GetClientRect(hWnd, &rc);
rc.top = 200;
hDC = GetDC(hWnd);
if(rc.top < rc.bottom)
FillRect(hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
ReleaseDC(hWnd, hDC);
}
return 1;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint (hWnd, &ps);
EndPaint (hWnd, &ps);
}
SHSipPreference(hWnd, SIP_UP); /* Hack! */
#ifdef USE_F_KEYS
adjust_extra_windows();
#endif
/* It does not happen often but I don't want to see tooltip traces */
wm->writeToScreen();
return 0;
case WM_ACTIVATE:
GraphicsResume();
SHHandleWMActivate(hWnd, wParam, lParam, &sai, SHA_INPUTDIALOG);
#ifdef USE_F_KEYS
adjust_extra_windows();
#endif
return 0;
case WM_HIBERNATE:
GraphicsSuspend();
return 0;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &sai);
#ifdef USE_F_KEYS
adjust_extra_windows();
#endif
return 0;
case WM_COMMAND:
switch(wParam)
{
case IDC_ABOUT:
break;
case IDC_EXIT:
DestroyWindow(hWnd);
break;
// Landscape mode is broken. This will be uncommented when it works
/*
case IDC_LANDSCAPE:
SetScreenMode(1);
SetCapture(hWnd); // to prevent input panel from getting taps
InvalidateRect(HWND_DESKTOP, NULL, TRUE);
break;
*/
}
return 0;
case WM_KEYDOWN:
if(wParam == VK_BACKSLASH)
wParam = VK_ESCAPE;
wm->_scumm->_keyPressed = mapKey(wParam);
break;
case WM_MOUSEMOVE:
{
int x = ((int16*)&lParam)[0];
int y = ((int16*)&lParam)[1];
Translate(&x, &y);
wm->_scumm->mouse.x = x;
wm->_scumm->mouse.y = y;
}
break;
case WM_LBUTTONDOWN:
{
int x = ((int16*)&lParam)[0];
int y = ((int16*)&lParam)[1];
Translate(&x, &y);
wm->_scumm->mouse.x = x;
wm->_scumm->mouse.y = y;
wm->_scumm->_leftBtnPressed |= 1;
if(y > 200)
{
if(x<160)
wm->_scumm->_keyPressed = VK_ESCAPE;
else
{
SetScreenMode(0); // restore normal tap logic
ReleaseCapture();
InvalidateRect(HWND_DESKTOP, NULL, TRUE);
}
}
}
break;
case WM_RBUTTONDOWN:
wm->_scumm->_rightBtnPressed |= 1;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// writeToScreen, setPalette and init are very port-specific
void WndMan::writeToScreen()
{
Blt(_vgabuf);
}
void WndMan::setPalette(byte *ctab, int first, int num) {
int i;
for (i=0; i<256; i++)
SetPalEntry(i, ctab[i*3+0]<<2, ctab[i*3+1]<<2, ctab[i*3+2]<<2);
}
void WndMan::init()
{
/* Retrieve the handle of this module */
hInst = GetModuleHandle(NULL);
/* Register the window class */
WNDCLASS wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = 0;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = 0;
wcex.lpszClassName = TEXT("ScummVM");
if (!RegisterClass(&wcex))
Error(TEXT("Cannot register window class!"));
hWnd = CreateWindow(TEXT("ScummVM"), TEXT("ScummVM"), WS_VISIBLE,
0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInst, NULL);
SetWindowLong(hWnd, GWL_USERDATA, (long)this);
ShowWindow(hWnd, SW_SHOW);
SHMENUBARINFO smbi;
smbi.cbSize = sizeof(smbi);
smbi.hwndParent = hWnd;
smbi.dwFlags = 0;
smbi.nToolBarId = IDM_MENU;
smbi.hInstRes = GetModuleHandle(NULL);
smbi.nBmpId = 0;
smbi.cBmpImages = 0;
smbi.hwndMB = NULL;
BOOL res = SHCreateMenuBar(&smbi);
GraphicsOn(hWnd);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
SetForegroundWindow(hWnd);
SHFullScreen(hWnd, SHFS_SHOWSIPBUTTON);
SHFullScreen(hWnd, SHFS_HIDETASKBAR);
#ifdef USE_F_KEYS
setup_extra_windows(hWnd);
#endif
}
//{{
bool WndMan::handleMessage() {
MSG msg;
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
return false;
if (msg.message==WM_QUIT) {
terminated=true;
exit(1);
return true;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
return true;
}
//}}
// This function is very similar to the one in windows.cpp except for
// one line removed.
void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {
byte *dst;
int i;
dst = (byte*)wm->_vgabuf + y*320 + x;
do {
memcpy(dst, src, w);
dst += 320;
src += 320;
} while (--h);
}
//{{
int clock;
void updateScreen(Scumm *s) {
if (s->_palDirtyMax != -1) {
wm->setPalette(s->_currentPalette, 0, 256);
s->_palDirtyMax = -1;
}
wm->writeToScreen();
}
void waitForTimer(Scumm *s, int delay) {
wm->handleMessage();
if (!veryFastMode) {
assert(delay<5000);
Sleep(delay);
}
}
void initGraphics(Scumm *s, bool fullScreen) {
if(fullScreen)
warning("Use SDL for fullscreen support");
}
void drawMouse(Scumm *s, int, int, int, byte*, bool) {
}
void drawMouse(Scumm *s, int x, int y, int w, int h, byte *buf, bool visible) {
}
void fill_buffer(int16 *buf, int len) {
memset(buf, 0, len*2);
scumm.mixWaves(buf, len);
}
void WndMan::prepare_header(WAVEHDR *wh, int i) {
memset(wh, 0, sizeof(WAVEHDR));
wh->lpData = (char*)malloc(BUFFER_SIZE);
wh->dwBufferLength = BUFFER_SIZE;
waveOutPrepareHeader(_handle, wh, sizeof(WAVEHDR));
fill_buffer((int16*)wh->lpData, wh->dwBufferLength>>1);
waveOutWrite(_handle, wh, sizeof(WAVEHDR));
}
void WndMan::sound_init() {
WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(wfx));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 1;
wfx.nSamplesPerSec = SAMPLES_PER_SEC;
wfx.nAvgBytesPerSec = SAMPLES_PER_SEC * BITS_PER_SAMPLE / 8;
wfx.wBitsPerSample = BITS_PER_SAMPLE;
wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8;
CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))&sound_thread, this, 0, &_threadId);
SetThreadPriority((void*)_threadId, THREAD_PRIORITY_HIGHEST);
_event = CreateEvent(NULL, false, false, NULL);
memset(_hdr,0,sizeof(_hdr));
waveOutOpen(&_handle, WAVE_MAPPER, &wfx, (long)_event, (long)this, CALLBACK_EVENT );
prepare_header(&_hdr[0], 0);
prepare_header(&_hdr[1], 1);
}
DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
int i;
bool signaled;
int time = GetTickCount(), cur;
while (1) {
cur = GetTickCount();
while (time < cur) {
sound.on_timer();
time += 10;
}
signaled = WaitForSingleObject(wm->_event, time - cur) == WAIT_OBJECT_0;
if (signaled) {
for(i=0; i<2; i++) {
WAVEHDR *hdr = &wm->_hdr[i];
if (hdr->dwFlags & WHDR_DONE) {
fill_buffer((int16*)hdr->lpData, hdr->dwBufferLength>>1);
waveOutWrite(wm->_handle, hdr, sizeof(WAVEHDR));
}
}
}
}
return 1; // not in windows.cpp - a bug!
}
//}}
BOOL CALLBACK SelectDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
RECT rc; GetWindowRect(hwndDlg, &rc);
MoveWindow(hwndDlg,
(GetSystemMetrics(SM_CXSCREEN)-rc.right+rc.left)/2,
(GetSystemMetrics(SM_CYSCREEN)-rc.bottom+rc.top)/2,
rc.right-rc.left, rc.bottom-rc.top, TRUE);
BringWindowToTop(hwndDlg);
}
return TRUE;
case WM_COMMAND:
EndDialog(hwndDlg, wParam);
return TRUE;
default:
return FALSE;
}
}
char* GameSelector()
{
switch(DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_GAMESELECT), HWND_DESKTOP, SelectDlgProc))
{
case IDC_MONKEY: return "monkey";
case IDC_MONKEY2: return "monkey2";
case IDC_ATLANTIS: return "atlantis";
case IDC_PLAYFATE: return "playfate";
case IDC_TENTACLE: return "tentacle";
case IDC_DOTTDEMO: return "dottdemo";
case IDC_SAMNMAX: return "samnmax";
case IDC_SNMDEMO: return "snmdemo";
default: return NULL;
}
}
// Directly corresponds to main in windows.cpp
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
int delta;
int tmp;
int argc = 2;
char* argv[2];
argv[0] = NULL;
argv[1] = GameSelector();
if(argv[1] == NULL)
return 0;
wm->init();
wm->sound_init();
wm->_vgabuf = (byte*)calloc(320,200);
wm->_scumm = &scumm;
// sound.initialize(&scumm);
// scumm._soundDriver = &sound;
scumm._soundDriver = NULL; // sound is not working yet and has been disabled
scumm._gui = &gui;
scumm.scummMain(argc, argv);
gui.init(&scumm);
delta = 0;
tmp = 0;
do
{
updateScreen(&scumm);
waitForTimer(&scumm, tmp*10);
if(gui._active)
{
gui.loop();
tmp = 5;
}
else
{
tmp = delta = scumm.scummLoop(delta);
tmp += tmp>>1;
if(scumm._fastMode)
tmp=1;
}
}
while(1);
return 0;
}
#ifdef USE_F_KEYS
/* Window for F-key input. Hack but some people asked for it. */
LRESULT CALLBACK FWindowProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch (nMsg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
RECT rc;
hDC = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
HGDIOBJ oldPen = SelectObject(hDC, (HGDIOBJ)GetStockObject(BLACK_PEN));
HGDIOBJ oldBr = SelectObject(hDC, (HGDIOBJ)GetStockObject(WHITE_BRUSH));
HGDIOBJ oldFont = SelectObject(hDC, (HGDIOBJ)GetStockObject(SYSTEM_FONT));
int rcWidth = rc.right-rc.left;
RECT rcItem;
rcItem.top = rc.top;
rcItem.bottom = rc.bottom;
POINT pts[2];
pts[0].y = rc.top;
pts[1].y = rc.bottom;
TCHAR text[4];
for(int i=0; i<10; i++)
{
wsprintf(text, TEXT("F%d"), i+1);
rcItem.left = rc.left+rcWidth*i/10;
rcItem.right = rc.left+rcWidth*(i+1)/10;
pts[0].x = pts[1].x = rcItem.right;
Polyline(hDC, pts, 2);
DrawText(hDC, text, -1, &rcItem, DT_CENTER|DT_VCENTER);
}
SelectObject(hDC, oldPen);
SelectObject(hDC, oldBr);
SelectObject(hDC, oldFont);
EndPaint(hwnd, &ps);
}
return 0;
case WM_LBUTTONDOWN:
{
int x = LOWORD(lParam);
RECT rc; GetWindowRect(hwnd, &rc);
int fnum = x*10/(rc.right-rc.left);
PostMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1+fnum, 0);
}
return 0;
}
return DefWindowProc(hwnd, nMsg, wParam, lParam);
}
void setup_extra_windows(HWND hwndTop)
{
LPTSTR fkeyname = TEXT("fkeys");
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = FWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = fkeyname;
RegisterClass(&wc);
hwndFKeys = CreateWindow(fkeyname,
fkeyname,
WS_VISIBLE|WS_CHILD,
0,
200,
GetSystemMetrics(SM_CXSCREEN),
20,
hwndTop,
(HMENU)100,
GetModuleHandle(NULL),
NULL);
}
void adjust_extra_windows()
{
SIPINFO si;
si.cbSize = sizeof(SIPINFO);
SHSipInfo(SPI_GETSIPINFO, 0, &si, 0);
if(si.fdwFlags & SIPF_ON)
{
int bottom = si.rcVisibleDesktop.bottom;
SetWindowPos(hwndFKeys, 0, 0, 200, GetSystemMetrics(SM_CXSCREEN), bottom-200,
SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER);
}
}
#endif

30
wince/resource.h Normal file
View file

@ -0,0 +1,30 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PocketSCUMM.rc
//
#define IDD_GAMESELECT 105
#define IDM_MENU 1000
#define IDC_ABOUT 1000
#define IDC_MONKEY 1000
#define IDC_EXIT 1001
#define IDC_MONKEY2 1001
#define IDC_ATLANTIS 1002
#define IDC_PLAYFATE 1003
#define IDC_TENTACLE 1004
#define IDC_DOTTDEMO 1005
#define IDC_SAMNMAX 1006
#define IDC_SNMDEMO 1007
#define ID_POCKETSCUMM 40005
#define IDS_CAP_POCKETSCUMM 40006
#define IDC_LANDSCAPE 40007
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40008
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

319
wince/screen.cpp Normal file
View file

@ -0,0 +1,319 @@
/* (C) 2001 Vasyl Tsvirkunov */
#include <windows.h>
#include "gx.h"
#include "screen.h"
#define SMOOTH
#define MAX_CLR 0x100
#ifdef SMOOTH
static UBYTE palRed[MAX_CLR];
static UBYTE palGreen[MAX_CLR];
static UBYTE palBlue[MAX_CLR];
#endif
static unsigned short pal[MAX_CLR];
GXDisplayProperties gxdp;
int active;
struct tScreenGeometry
{
long width;
long height;
long startoffset;
long sourceoffset;
long linestep;
long pixelstep;
long xSkipMask;
long xLimit;
long lineLimit;
};
tScreenGeometry geom[3];
int currentScreenMode = 0;
int useMode = 0;
int maxMode = 2;
void SetScreenMode(int mode)
{
currentScreenMode = mode;
if(currentScreenMode > maxMode)
currentScreenMode = 0;
}
int GetScreenMode()
{
return currentScreenMode;
}
void GraphicsSuspend()
{
if(active)
{
active = 0;
GXSuspend();
}
}
void GraphicsResume()
{
if(!active)
{
active = 1;
GXResume();
}
}
void GraphicsOff(void)
{
GXCloseDisplay();
active = 0;
}
int GraphicsOn(HWND hWndMain)
{
GXOpenDisplay(hWndMain, GX_FULLSCREEN);
gxdp = GXGetDisplayProperties();
if((gxdp.ffFormat & (kfDirect555 | kfDirect565)) == 0 || gxdp.cxWidth < 240 || gxdp.cyHeight < 240)
{
GraphicsOff();
return 1;
}
// portrait
geom[0].width = gxdp.cxWidth; // 240
geom[0].height = gxdp.cyHeight; // 320
geom[0].startoffset = 0;
geom[0].sourceoffset = 0;
geom[0].linestep = gxdp.cbyPitch;
geom[0].pixelstep = gxdp.cbxPitch;
geom[0].xSkipMask = gxdp.cxWidth < 320 ? 0x00000003 : 0xffffffff;
geom[0].xLimit = 320; // skip 1/4
geom[0].lineLimit = 320*200;
// left handed landscape
geom[1].width = gxdp.cyHeight; // 320
geom[1].height = gxdp.cxWidth; // 240
geom[1].startoffset = gxdp.cbyPitch*(gxdp.cyHeight-1);
geom[1].sourceoffset = 0;
geom[1].linestep = gxdp.cbxPitch;
geom[1].pixelstep = -gxdp.cbyPitch;
geom[1].xSkipMask = 0xffffffff;
geom[1].xLimit = 320; // no skip
geom[1].lineLimit = 320*200;
// right handed landscape
geom[2].width = gxdp.cyHeight; // 320
geom[2].height = gxdp.cxWidth; // 240
geom[2].startoffset = gxdp.cbxPitch*(gxdp.cxWidth-1);
geom[2].sourceoffset = 0;
geom[2].linestep = -gxdp.cbxPitch;
geom[2].pixelstep = gxdp.cbyPitch;
geom[2].xSkipMask = 0xffffffff;
geom[2].xLimit = 320; // no skip
geom[2].lineLimit = 320*200;
if(gxdp.cyHeight < 320)
maxMode = 0; // portrait only!
active = 1;
return 0;
}
void SetPalEntry(int ent, UBYTE r, UBYTE g, UBYTE b)
{
if (ent >= MAX_CLR)
return;
#ifdef SMOOTH
palRed[ent] = r;
palGreen[ent] = g;
palBlue[ent] = b;
#endif
if(gxdp.ffFormat & kfDirect565)
pal[ent] = ((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3);
else if(gxdp.ffFormat & kfDirect555)
pal[ent] = ((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3);
}
void Cls()
{
int x, y;
UBYTE* dst;
UBYTE *scraddr;
scraddr = (UBYTE*)GXBeginDraw();
if(scraddr)
{
for(y=0; y<geom[useMode].height; y++)
{
dst = scraddr+geom[useMode].startoffset;
for(x=0; x<geom[useMode].width; x++)
{
*(unsigned short*)dst = 0;
dst += geom[useMode].pixelstep;
}
scraddr += geom[useMode].linestep;
}
GXEndDraw();
}
}
int counter = 0;
void Blt(UBYTE * scr_ptr)
{
static UBYTE *src;
static UBYTE *dst;
static UBYTE *scraddr;
static UBYTE *scr_ptr_limit;
static UBYTE *src_limit;
static long pixelstep;
static long linestep;
static long skipmask;
#ifdef SMOOTH
static bool b565 = (gxdp.ffFormat & kfDirect565);
#endif
if(!active)
{
Sleep(100);
return;
}
/* Update screen mode, also thread protection by doing this */
if(useMode != currentScreenMode)
{
useMode = currentScreenMode;
Cls();
}
scraddr = (UBYTE*)GXBeginDraw();
if(scraddr)
{
scraddr += geom[useMode].startoffset;
scr_ptr += geom[useMode].sourceoffset;
scr_ptr_limit = scr_ptr + geom[useMode].lineLimit;
pixelstep = geom[useMode].pixelstep;
linestep = geom[useMode].linestep;
src_limit = scr_ptr + geom[useMode].xLimit;
skipmask = geom[useMode].xSkipMask;
/* Internal pixel loops */
#ifdef SMOOTH
if(skipmask == 3)
{
while(scr_ptr < scr_ptr_limit)
{
src = scr_ptr;
dst = scraddr;
while(src < src_limit)
{
UBYTE r, g, b;
r = (3*palRed[*(src+0)] + palRed[*(src+1)])>>2;
g = (3*palGreen[*(src+0)] + palGreen[*(src+1)])>>2;
b = (3*palBlue[*(src+0)] + palBlue[*(src+1)])>>2;
if(b565)
*(unsigned short*)dst = ((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3);
else
*(unsigned short*)dst = ((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3);
dst += pixelstep;
r = (palRed[*(src+1)] + palRed[*(src+2)])>>1;
g = (palGreen[*(src+1)] + palGreen[*(src+2)])>>1;
b = (palBlue[*(src+1)] + palBlue[*(src+2)])>>1;
if(b565)
*(unsigned short*)dst = ((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3);
else
*(unsigned short*)dst = ((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3);
dst += pixelstep;
r = (palRed[*(src+2)] + 3*palRed[*(src+3)])>>2;
g = (palGreen[*(src+2)] + 3*palGreen[*(src+3)])>>2;
b = (palBlue[*(src+2)] + 3*palBlue[*(src+3)])>>2;
if(b565)
*(unsigned short*)dst = ((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3);
else
*(unsigned short*)dst = ((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3);
dst += pixelstep;
src += 4;
}
scraddr += linestep;
scr_ptr += 320;
src_limit += 320;
}
}
else
#endif
if(skipmask != 0xffffffff)
{
while(scr_ptr < scr_ptr_limit)
{
src = scr_ptr;
dst = scraddr;
while(src < src_limit)
{
if((long)src & skipmask)
{
*(unsigned short*)dst = pal[*src];
dst += pixelstep;
}
src ++;
}
scraddr += linestep;
scr_ptr += 320;
src_limit += 320;
}
}
else
{
while(scr_ptr < scr_ptr_limit)
{
src = scr_ptr;
dst = scraddr;
while(src < src_limit)
{
*(unsigned short*)dst = pal[*src];
dst += pixelstep;
src ++;
}
scraddr += linestep;
scr_ptr += 320;
src_limit += 320;
}
}
GXEndDraw();
}
}
void Translate(int* px, int* py)
{
int x, y;
switch(currentScreenMode)
{
case 0: /* portrait */
*px = *px*4/3;
break;
case 1: /* landscape left */
x = 320 - *py;
y = *px;
*px = x;
*py = y;
break;
case 2: /* landscape right */
x = *py;
y = 240 - *px;
*px = x;
*py = y;
break;
}
}

24
wince/screen.h Normal file
View file

@ -0,0 +1,24 @@
/* (C) 2001 Vasyl Tsvirkunov */
#ifndef SCREEN_H
#define SCREEN_H
#ifndef UBYTE
#define UBYTE unsigned char
#endif
int GraphicsOn(HWND hWndMain);
void GraphicsOff();
void GraphicsSuspend();
void GraphicsResume();
void SetPalEntry(int ent, UBYTE r, UBYTE g, UBYTE b);
void Blt(UBYTE * scr_ptr);
/* meaning: 0 - portrait, 1 - left hand landscape, 2 - right hand landscape */
void SetScreenMode(int mode);
int GetScreenMode();
void Translate(int* x, int* y);
#endif

4
wince/sdl.h Normal file
View file

@ -0,0 +1,4 @@
/* dummy header */
// A little hack...
#undef NOCTLMGR